@thirdfy/agent-cli 0.1.38 → 0.1.39
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 +11 -0
- package/README.md +26 -13
- package/bin/thirdfy-agent.mjs +84 -17
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.39] - 2026-05-17
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Framework guidance for Hermes, OpenClaw, and Claude Managed Agents in `help onboarding`, README, and command reference so agents can choose CLI/MCP rails correctly.
|
|
12
|
+
- Gator-style `delegation grant` alias and clearer external-wallet delegation next steps.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Fresh solo profiles now default to `agent_wallet`, persist/resolve owner `userDid`, and use owner-matched mirror scope for hybrid validation.
|
|
17
|
+
|
|
7
18
|
## [0.1.38] - 2026-05-17
|
|
8
19
|
|
|
9
20
|
### Fixed
|
package/README.md
CHANGED
|
@@ -9,12 +9,13 @@ Use it to:
|
|
|
9
9
|
- run governance preflight checks
|
|
10
10
|
- queue execute-intent requests with idempotency
|
|
11
11
|
- poll intent status with stable JSON output for automation
|
|
12
|
-
- choose execution topology with one switch: `
|
|
12
|
+
- choose execution topology with one switch: `agent_wallet`, `self`, `hybrid`, or `thirdfy`
|
|
13
13
|
- configure profile-driven defaults (`personal`, `builder`, `network`)
|
|
14
14
|
|
|
15
15
|
If you want the full developer docs, start here:
|
|
16
|
-
- [Thirdfy Agent CLI
|
|
17
|
-
- [
|
|
16
|
+
- [Thirdfy Agent CLI hub](https://docs.thirdfy.com/documentation/agent-cli) (guided chapters)
|
|
17
|
+
- [Thirdfy Agent CLI — full reference](https://docs.thirdfy.com/documentation/api/thirdfy-agent-cli)
|
|
18
|
+
- [API Reference home](https://docs.thirdfy.com/documentation/api/api-reference)
|
|
18
19
|
- [LLM docs map (llms.txt)](https://docs.thirdfy.com/llms.txt)
|
|
19
20
|
- [LLM full API snapshot (llms-full.txt)](https://docs.thirdfy.com/llms-full.txt)
|
|
20
21
|
- [Provider docs index (repo)](./docs/providers/index.md)
|
|
@@ -41,7 +42,7 @@ npx @thirdfy/agent-cli --help
|
|
|
41
42
|
|
|
42
43
|
## Release notes
|
|
43
44
|
|
|
44
|
-
Version history and highlights: [CHANGELOG.md](./CHANGELOG.md). **v0.1.38** is a **documentation and metadata patch**: it republishes to npm so the package homepage matches the updated `README.md` on `main`, and aligns root `package-lock.json` version fields with `package.json`. **v0.1.37** adds **email OTP** `thirdfy-agent login email` (send code, then complete with `--code --accept-terms`), **`help onboarding`**, **`doctor auth`**, **`wallet list`**, and **masked `whoami`** output so agents and operators get first-run guidance without dumping secrets.
|
|
45
|
+
Version history and highlights: [CHANGELOG.md](./CHANGELOG.md). **v0.1.39** makes `agent_wallet` the fresh solo default, adds framework guidance for Hermes/OpenClaw/Claude Managed Agents, clarifies Gator/ERC-7710 delegation flows, and keeps BYOW/self plus hybrid/thirdfy mode switching explicit. **v0.1.38** is a **documentation and metadata patch**: it republishes to npm so the package homepage matches the updated `README.md` on `main`, and aligns root `package-lock.json` version fields with `package.json`. **v0.1.37** adds **email OTP** `thirdfy-agent login email` (send code, then complete with `--code --accept-terms`), **`help onboarding`**, **`doctor auth`**, **`wallet list`**, and **masked `whoami`** output so agents and operators get first-run guidance without dumping secrets. Earlier releases added provider discovery parity, portfolio analytics, managed-wallet swap normalization, and **self/build-tx** swap human-decimal `amountIn` parity when using `amountInHuman` + `tokenInDecimals`.
|
|
45
46
|
|
|
46
47
|
**Maintainers — npm:** follow [docs/releasing.md](./docs/releasing.md). From a clone with gitignored `.env`, use `npm run publish:npm:local -- --dry-run` then `npm run publish:npm:local`. Or run `npm run release:npm` after exporting tokens in the shell. Never commit npm tokens — use [.env.example](./.env.example) as a template only.
|
|
47
48
|
|
|
@@ -103,7 +104,7 @@ thirdfy-agent logout --json
|
|
|
103
104
|
thirdfy-agent logout --all --json
|
|
104
105
|
```
|
|
105
106
|
|
|
106
|
-
`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,
|
|
107
|
+
`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 plus the owner `userDid` when Privy returns them, stores a new agent API key when first-run bootstrap issues one, and defaults new solo profiles to `agent_wallet`. Use `--not-interactive` / `--ni` in automation so missing input fails fast instead of prompting — place **`--ni` after the `login email` subcommand** (for example `thirdfy-agent login email you@example.com --code … --accept-terms --ni`); a leading `thirdfy-agent --ni login email …` is parsed incorrectly because `--ni` would consume the `login` token as its value.
|
|
107
108
|
|
|
108
109
|
`logout --all` is provider-agnostic: it attempts owner-session revocation when a session token exists, then always clears local credentials.
|
|
109
110
|
|
|
@@ -149,15 +150,17 @@ thirdfy-agent bootstrap complete --agent-key "0xYOUR_AGENT_KEY" --challenge-id "
|
|
|
149
150
|
|
|
150
151
|
`thirdfy-agent` supports one command surface with four run modes:
|
|
151
152
|
|
|
152
|
-
- `--run-mode
|
|
153
|
-
- `--run-mode self` -> self-custody rail (`build-tx` flow
|
|
153
|
+
- `--run-mode agent_wallet` -> managed solo wallet execution rail and fresh email-login default
|
|
154
|
+
- `--run-mode self` -> self-custody rail (`build-tx` flow)
|
|
154
155
|
- `--run-mode hybrid` -> self-custody + governance mirror metadata (default for `profile=builder`)
|
|
155
|
-
- `--run-mode
|
|
156
|
+
- `--run-mode thirdfy` -> Thirdfy-governed execute-intent rail (default for `profile=network`)
|
|
156
157
|
|
|
157
158
|
| Goal | Recommended mode | Why |
|
|
158
159
|
| --- | --- | --- |
|
|
160
|
+
| Fast solo managed-wallet trading | `agent_wallet` | Uses `/execution-wallet` + `/execute`; owner `userDid` comes from login config. |
|
|
159
161
|
| BYOW signing and local custody | `self` | Keeps signing and broadcast on your wallet path. |
|
|
160
|
-
|
|
|
162
|
+
| External wallet delegated execution | `hybrid` or `thirdfy` after `delegation create/activate` | Uses Gator/ERC-7710 authority from the user wallet to the Thirdfy/session executor. |
|
|
163
|
+
| Publisher fan-out / subscriber execution | `thirdfy` | Uses delegated governance rail and active `delegation_bindings`. |
|
|
161
164
|
| Self execution plus governance mirror checks | `hybrid` | Preserves local execution while emitting managed-lane mirrors. |
|
|
162
165
|
| Managed wallet primary + governance mirror checks | `hybrid --hybrid-wallet-mode agent_wallet` | Uses managed wallet as primary hybrid path while still running Thirdfy mirror checks. |
|
|
163
166
|
|
|
@@ -166,7 +169,7 @@ Auth expectations by mode:
|
|
|
166
169
|
- `self`: requires execution identity (`agentApiKey`) today; keyless self lane is blocked with deterministic `SELF_OPEN_DISABLED`.
|
|
167
170
|
- `hybrid`: requires execution identity and governed mirror semantics (`--hybrid-wallet-mode self|agent_wallet`, default `self`).
|
|
168
171
|
- `thirdfy`: requires execution identity and delegated governance path.
|
|
169
|
-
- `agent_wallet`: requires execution identity and
|
|
172
|
+
- `agent_wallet`: requires execution identity and owner `userDid`, but does not require subscriber delegation when the owner identity matches the agent wallet/creator.
|
|
170
173
|
- custody mode defaults are profile-aware:
|
|
171
174
|
- `managed` default for `thirdfy`
|
|
172
175
|
- `external` default for `self` and `hybrid`
|
|
@@ -177,7 +180,7 @@ Selection precedence:
|
|
|
177
180
|
1. `--run-mode`
|
|
178
181
|
2. `THIRDFY_RUN_MODE`
|
|
179
182
|
3. saved profile config (`~/.thirdfy/config.json`)
|
|
180
|
-
4. profile default
|
|
183
|
+
4. profile default (`personal=agent_wallet`, `builder=hybrid`, `network=thirdfy`)
|
|
181
184
|
|
|
182
185
|
Profile commands:
|
|
183
186
|
|
|
@@ -189,6 +192,16 @@ thirdfy-agent whoami --json
|
|
|
189
192
|
|
|
190
193
|
`profile use --profile <name>` resets run mode to that profile default unless `--run-mode` is explicitly provided.
|
|
191
194
|
|
|
195
|
+
## Framework Guidance
|
|
196
|
+
|
|
197
|
+
Use the same execution identities across frameworks, but choose the rail by who signs and who the agent acts for:
|
|
198
|
+
|
|
199
|
+
- **Hermes agents:** provision the Thirdfy profile and env before the Hermes dashboard/runtime starts, run `thirdfy-agent doctor auth` and `doctor self` during startup checks, prefer `agent_wallet` for the agent’s own managed wallet, and keep `thirdfy` for publisher/fanout or delegated external-wallet execution.
|
|
200
|
+
- **OpenClaw agents:** store Thirdfy credentials as runtime secrets, call `thirdfy-agent actions --provider <id>` before planning, use `run --run-mode agent_wallet` for own-wallet actions, use `self` only when OWS/local signing is configured, and switch to `hybrid`/`thirdfy` only after delegation readiness is confirmed.
|
|
201
|
+
- **Claude Managed Agents:** prefer MCP `agentRun` / `walletExecute` for solo managed execution, `buildTx` / `walletSign` for BYOW local signing, and `executeIntent` only for subscriber fanout or explicit validation-only mirror previews. The CLI remains useful for smoke checks and local operator recovery.
|
|
202
|
+
|
|
203
|
+
For all frameworks, treat `agentApiKey` as a hidden execution credential in secret storage, keep owner-session tokens short lived, and verify mode requirements with `thirdfy-agent help onboarding --json`.
|
|
204
|
+
|
|
192
205
|
### One-command self execution (BYOW)
|
|
193
206
|
|
|
194
207
|
Use `--broadcast` with `run --run-mode self` to keep one deterministic command for build/sign/send:
|
|
@@ -400,7 +413,7 @@ Managed-self execution performs strict wallet preflight and returns deterministi
|
|
|
400
413
|
## More docs
|
|
401
414
|
|
|
402
415
|
- OpenClaw CLI onboarding flow:
|
|
403
|
-
[docs.thirdfy.com/api/thirdfy-agent-cli#create-an-openclaw-agent-with-the-cli](https://docs.thirdfy.com/api/thirdfy-agent-cli#create-an-openclaw-agent-with-the-cli)
|
|
416
|
+
[docs.thirdfy.com/documentation/api/thirdfy-agent-cli#create-an-openclaw-agent-with-the-cli](https://docs.thirdfy.com/documentation/api/thirdfy-agent-cli#create-an-openclaw-agent-with-the-cli)
|
|
404
417
|
- Creator platform (agent registration and keys):
|
|
405
418
|
[thirdfy.com/creator](https://thirdfy.com/creator)
|
|
406
419
|
|
|
@@ -416,7 +429,7 @@ npm run e2e:managed:delegation:parity
|
|
|
416
429
|
|
|
417
430
|
## Release
|
|
418
431
|
|
|
419
|
-
Version history and user-facing notes: [CHANGELOG.md](./CHANGELOG.md) (for example [v0.1.38](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.38) — npm README + lockfile metadata alignment; [v0.1.37](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.37) — email OTP login, onboarding help, auth doctor, wallet list, masked `whoami`). **Before every version bump or npm publish:** update this **README** (release notes paragraph, quick start, and command groups) so the npm package page matches what ships; keep `CHANGELOG.md`, [command reference](./docs/command-reference.md), and MCP summaries aligned when discovery or onboarding surfaces change.
|
|
432
|
+
Version history and user-facing notes: [CHANGELOG.md](./CHANGELOG.md) (for example [v0.1.39](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.39) — agent-wallet solo default, framework guidance, and delegation UX; [v0.1.38](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.38) — npm README + lockfile metadata alignment; [v0.1.37](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.37) — email OTP login, onboarding help, auth doctor, wallet list, masked `whoami`). **Before every version bump or npm publish:** update this **README** (release notes paragraph, quick start, and command groups) so the npm package page matches what ships; keep `CHANGELOG.md`, [command reference](./docs/command-reference.md), and MCP summaries aligned when discovery or onboarding surfaces change.
|
|
420
433
|
|
|
421
434
|
```bash
|
|
422
435
|
npm version patch
|
package/bin/thirdfy-agent.mjs
CHANGED
|
@@ -43,7 +43,7 @@ const CUSTODY_MODES = ['managed', 'external'];
|
|
|
43
43
|
const EFFECT_CHECK_MODES = ['strict', 'relaxed', 'off'];
|
|
44
44
|
let negotiatedCapabilitiesCache = null;
|
|
45
45
|
const PROFILE_DEFAULTS = {
|
|
46
|
-
personal: '
|
|
46
|
+
personal: 'agent_wallet',
|
|
47
47
|
builder: 'hybrid',
|
|
48
48
|
network: 'thirdfy',
|
|
49
49
|
};
|
|
@@ -224,6 +224,7 @@ async function main() {
|
|
|
224
224
|
await commandTrackAction(context, subFlags, capabilities);
|
|
225
225
|
return;
|
|
226
226
|
case 'delegation create':
|
|
227
|
+
case 'delegation grant':
|
|
227
228
|
await commandDelegationCreate(context, subFlags, capabilities);
|
|
228
229
|
return;
|
|
229
230
|
case 'delegation init-custodial':
|
|
@@ -1432,7 +1433,17 @@ async function commandDelegationCreate(ctx, flags, capabilities) {
|
|
|
1432
1433
|
success,
|
|
1433
1434
|
code: success ? 'DELEGATION_CREATED' : 'DELEGATION_CREATE_FAILED',
|
|
1434
1435
|
message: response?.message || (success ? 'Delegation payload created' : 'Delegation create failed'),
|
|
1435
|
-
data:
|
|
1436
|
+
data: {
|
|
1437
|
+
...response,
|
|
1438
|
+
delegationModel: 'gator_erc7710',
|
|
1439
|
+
nextSteps: success
|
|
1440
|
+
? [
|
|
1441
|
+
'Sign data.delegation with the external wallet or OWS account that owns --owner-address.',
|
|
1442
|
+
'Run `thirdfy-agent delegation activate --agent-key <key> --wallet-address <owner> --session-account-address <delegate> --delegation-manager <manager> --delegation <json> --signature <hex>`.',
|
|
1443
|
+
'Verify with `thirdfy-agent delegation inspect --agent-key <key> --verify`, then use `delegation redeem` or run with --run-mode hybrid|thirdfy for delegated execution.',
|
|
1444
|
+
]
|
|
1445
|
+
: [],
|
|
1446
|
+
},
|
|
1436
1447
|
meta: {
|
|
1437
1448
|
apiBase: ctx.apiBase,
|
|
1438
1449
|
capabilitiesVersion: capabilities?.contractVersion || null,
|
|
@@ -1533,7 +1544,16 @@ async function commandDelegationActivate(ctx, flags, capabilities) {
|
|
|
1533
1544
|
success,
|
|
1534
1545
|
code: success ? 'DELEGATION_ACTIVATED' : 'DELEGATION_ACTIVATE_FAILED',
|
|
1535
1546
|
message: response?.message || (success ? 'Delegation activated' : 'Delegation activate failed'),
|
|
1536
|
-
data:
|
|
1547
|
+
data: {
|
|
1548
|
+
...response,
|
|
1549
|
+
delegationModel: 'gator_erc7710',
|
|
1550
|
+
nextSteps: success
|
|
1551
|
+
? [
|
|
1552
|
+
'Run `thirdfy-agent delegation inspect --agent-key <key> --verify` to confirm period allowance and revocation state.',
|
|
1553
|
+
'Use `thirdfy-agent delegation redeem --run-mode hybrid|thirdfy ...` when Thirdfy/session executor should act under this external-wallet delegation.',
|
|
1554
|
+
]
|
|
1555
|
+
: [],
|
|
1556
|
+
},
|
|
1537
1557
|
meta: {
|
|
1538
1558
|
apiBase: ctx.apiBase,
|
|
1539
1559
|
capabilitiesVersion: capabilities?.contractVersion || null,
|
|
@@ -2434,8 +2454,8 @@ async function commandProfileShow(ctx, _flags) {
|
|
|
2434
2454
|
message: 'Profile configuration loaded',
|
|
2435
2455
|
data: {
|
|
2436
2456
|
profile: ctx.profile || config.profile || 'personal',
|
|
2437
|
-
runMode: ctx.runMode || config.runMode || '
|
|
2438
|
-
custodyMode: ctx.custodyMode || config.custodyMode || defaultCustodyModeForRunMode(ctx.runMode || config.runMode || '
|
|
2457
|
+
runMode: ctx.runMode || config.runMode || 'agent_wallet',
|
|
2458
|
+
custodyMode: ctx.custodyMode || config.custodyMode || defaultCustodyModeForRunMode(ctx.runMode || config.runMode || 'agent_wallet'),
|
|
2439
2459
|
profileDefaults: PROFILE_DEFAULTS,
|
|
2440
2460
|
configPath: getProfileConfigPath(),
|
|
2441
2461
|
config,
|
|
@@ -2455,7 +2475,7 @@ function maskSecret(value) {
|
|
|
2455
2475
|
function buildOnboardingHelp(ctx) {
|
|
2456
2476
|
return {
|
|
2457
2477
|
title: 'Thirdfy Agent CLI onboarding',
|
|
2458
|
-
summary: 'Use email OTP, wallet-sign, or existing credentials to create owner auth, wallets, and agent execution credentials.',
|
|
2478
|
+
summary: 'Use email OTP, wallet-sign, or existing credentials to create owner auth, wallets, and hidden agent execution credentials. Fresh solo profiles default to agent_wallet.',
|
|
2459
2479
|
paths: [
|
|
2460
2480
|
{
|
|
2461
2481
|
id: 'email_otp',
|
|
@@ -2466,6 +2486,7 @@ function buildOnboardingHelp(ctx) {
|
|
|
2466
2486
|
'thirdfy-agent login email user@example.com --code <otp> --accept-terms --key-name "My Agent"',
|
|
2467
2487
|
'thirdfy-agent whoami',
|
|
2468
2488
|
'thirdfy-agent managed wallet init --chain-id 8453',
|
|
2489
|
+
'thirdfy-agent preflight --run-mode agent_wallet --action <action> --params <json> --json',
|
|
2469
2490
|
],
|
|
2470
2491
|
},
|
|
2471
2492
|
{
|
|
@@ -2499,6 +2520,21 @@ function buildOnboardingHelp(ctx) {
|
|
|
2499
2520
|
'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
2521
|
rule: 'Commands must fail fast instead of waiting for prompts when required input is missing.',
|
|
2501
2522
|
},
|
|
2523
|
+
executionModes: {
|
|
2524
|
+
agent_wallet: 'Solo managed wallet execution through /execution-wallet + /execute; no subscriber binding when owner userDid matches.',
|
|
2525
|
+
self: 'BYOW/OWS local signing through build-tx, wallet sign, and wallet submit.',
|
|
2526
|
+
hybrid: 'Primary self or agent_wallet execution with optional Thirdfy mirror validation.',
|
|
2527
|
+
thirdfy: 'Publisher/fanout execute-intent; requires active subscriber/delegation bindings for writes.',
|
|
2528
|
+
externalDelegation: 'Use delegation create/grant -> sign -> activate -> inspect/balance -> redeem for Gator/ERC-7710 external-wallet authority.',
|
|
2529
|
+
},
|
|
2530
|
+
frameworkGuidance: {
|
|
2531
|
+
hermes:
|
|
2532
|
+
'Hermes agents should receive a pre-provisioned Thirdfy profile/env, run doctor auth/self at startup, use agent_wallet for managed solo writes, and keep strategy logic separate from CLI secrets.',
|
|
2533
|
+
openclaw:
|
|
2534
|
+
'OpenClaw agents should keep Thirdfy credentials in runtime secrets, use actions discovery before planning, prefer run --run-mode agent_wallet for own-wallet execution, and use thirdfy only for publisher/fanout.',
|
|
2535
|
+
claudeManagedAgents:
|
|
2536
|
+
'Claude Managed Agents should use MCP agentRun/walletExecute for solo managed execution, walletSign/buildTx for BYOW, and executeIntent only for fanout or mirror previews.',
|
|
2537
|
+
},
|
|
2502
2538
|
apiBase: ctx.apiBase,
|
|
2503
2539
|
};
|
|
2504
2540
|
}
|
|
@@ -2518,14 +2554,15 @@ async function commandWhoami(ctx, _flags) {
|
|
|
2518
2554
|
const auth = config.auth && typeof config.auth === 'object' ? config.auth : {};
|
|
2519
2555
|
const agent = config.agent && typeof config.agent === 'object' ? config.agent : {};
|
|
2520
2556
|
const wallets = config.wallets && typeof config.wallets === 'object' ? config.wallets : {};
|
|
2557
|
+
const runMode = ctx.runMode || config.runMode || 'agent_wallet';
|
|
2521
2558
|
printEnvelope({
|
|
2522
2559
|
success: true,
|
|
2523
2560
|
code: 'WHOAMI_OK',
|
|
2524
2561
|
message: 'Thirdfy CLI identity loaded',
|
|
2525
2562
|
data: {
|
|
2526
2563
|
profile: ctx.profile || config.profile || 'personal',
|
|
2527
|
-
runMode
|
|
2528
|
-
custodyMode: ctx.custodyMode || config.custodyMode || defaultCustodyModeForRunMode(
|
|
2564
|
+
runMode,
|
|
2565
|
+
custodyMode: ctx.custodyMode || config.custodyMode || defaultCustodyModeForRunMode(runMode),
|
|
2529
2566
|
auth: {
|
|
2530
2567
|
source: auth.source || null,
|
|
2531
2568
|
hasAuthToken: Boolean(auth.authToken),
|
|
@@ -2539,6 +2576,7 @@ async function commandWhoami(ctx, _flags) {
|
|
|
2539
2576
|
agentKey: agent.agentKey || null,
|
|
2540
2577
|
},
|
|
2541
2578
|
wallets: {
|
|
2579
|
+
userDid: wallets.userDid || config.identity?.userDid || null,
|
|
2542
2580
|
primaryEvmWallet: wallets.primaryEvmWallet || null,
|
|
2543
2581
|
evm: Array.isArray(wallets.evm) ? wallets.evm : [],
|
|
2544
2582
|
solana: Array.isArray(wallets.solana) ? wallets.solana : [],
|
|
@@ -2571,6 +2609,8 @@ async function commandDoctorAuth(ctx, _flags) {
|
|
|
2571
2609
|
const config = loadProfileConfig();
|
|
2572
2610
|
const auth = config.auth && typeof config.auth === 'object' ? config.auth : {};
|
|
2573
2611
|
const agent = config.agent && typeof config.agent === 'object' ? config.agent : {};
|
|
2612
|
+
const runMode = normalizeRunMode(ctx.runMode || config.runMode || 'agent_wallet');
|
|
2613
|
+
const userDid = resolveEffectiveUserDid({});
|
|
2574
2614
|
const ownerSessionTokenFromEnv = String(process.env.THIRDFY_OWNER_SESSION_TOKEN || '').trim();
|
|
2575
2615
|
const authTokenFromEnv = String(process.env.THIRDFY_AUTH_TOKEN || '').trim();
|
|
2576
2616
|
const agentApiKeyFromEnv = String(process.env.THIRDFY_AGENT_API_KEY || '').trim();
|
|
@@ -2598,6 +2638,14 @@ async function commandDoctorAuth(ctx, _flags) {
|
|
|
2598
2638
|
? 'agent API key from THIRDFY_AGENT_API_KEY'
|
|
2599
2639
|
: 'not stored yet (optional until execution); complete onboarding or bootstrap to add one',
|
|
2600
2640
|
},
|
|
2641
|
+
{
|
|
2642
|
+
name: 'user-did',
|
|
2643
|
+
optional: runMode !== 'agent_wallet',
|
|
2644
|
+
ok: Boolean(userDid),
|
|
2645
|
+
detail: userDid
|
|
2646
|
+
? `user DID available (${userDid})`
|
|
2647
|
+
: 'missing user DID; run `thirdfy-agent login email <email>` or set THIRDFY_USER_DID',
|
|
2648
|
+
},
|
|
2601
2649
|
{
|
|
2602
2650
|
name: 'wallet-profile',
|
|
2603
2651
|
ok: Boolean(config.wallets?.primaryEvmWallet || (Array.isArray(config.wallets?.evm) && config.wallets.evm.length)),
|
|
@@ -2660,7 +2708,7 @@ async function commandLogin(ctx, flags) {
|
|
|
2660
2708
|
const current = loadProfileConfig();
|
|
2661
2709
|
const authToken = String(flags.authToken || process.env.THIRDFY_AUTH_TOKEN || '').trim();
|
|
2662
2710
|
let ownerSessionToken = String(flags.ownerSessionToken || process.env.THIRDFY_OWNER_SESSION_TOKEN || '').trim();
|
|
2663
|
-
const loginRunMode = normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || '
|
|
2711
|
+
const loginRunMode = normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || 'agent_wallet');
|
|
2664
2712
|
const custodyMode = normalizeCustodyMode(
|
|
2665
2713
|
flags.custodyMode || current.custodyMode || process.env.THIRDFY_CUSTODY_MODE,
|
|
2666
2714
|
loginRunMode
|
|
@@ -2842,10 +2890,10 @@ async function commandLoginEmail(ctx, flags) {
|
|
|
2842
2890
|
acceptTerms: true,
|
|
2843
2891
|
keyName,
|
|
2844
2892
|
agentKey: String(flags.agentKey || '').trim() || undefined,
|
|
2845
|
-
runMode: normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || '
|
|
2893
|
+
runMode: normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || 'agent_wallet'),
|
|
2846
2894
|
custodyMode: normalizeCustodyMode(
|
|
2847
2895
|
flags.custodyMode || current.custodyMode || process.env.THIRDFY_CUSTODY_MODE,
|
|
2848
|
-
normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || '
|
|
2896
|
+
normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || 'agent_wallet')
|
|
2849
2897
|
),
|
|
2850
2898
|
bootstrapAgent: !parseBooleanFlag(flags.noBootstrapAgent, false),
|
|
2851
2899
|
rotateAgentKey: parseBooleanFlag(flags.rotateAgentKey, false),
|
|
@@ -2856,12 +2904,14 @@ async function commandLoginEmail(ctx, flags) {
|
|
|
2856
2904
|
const agentApiKey = String(bootstrap.agentApiKey || '').trim();
|
|
2857
2905
|
const agentKey = String(bootstrap.agentKey || data.owner?.creatorWallet || '').trim();
|
|
2858
2906
|
const wallets = data.wallets && typeof data.wallets === 'object' ? data.wallets : {};
|
|
2907
|
+
const userDid = String(data.owner?.creatorDid || wallets.userDid || '').trim();
|
|
2859
2908
|
const primaryEvmWallet = String(wallets.primaryEvmWallet || data.owner?.creatorWallet || '').trim();
|
|
2860
2909
|
const persistedWallets = {
|
|
2861
2910
|
...wallets,
|
|
2911
|
+
...(userDid ? { userDid } : {}),
|
|
2862
2912
|
...(primaryEvmWallet ? { primaryEvmWallet } : {}),
|
|
2863
2913
|
};
|
|
2864
|
-
const runMode = normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || '
|
|
2914
|
+
const runMode = normalizeRunMode(flags.runMode || current.runMode || process.env.THIRDFY_RUN_MODE || 'agent_wallet');
|
|
2865
2915
|
const custodyMode = normalizeCustodyMode(flags.custodyMode || current.custodyMode || process.env.THIRDFY_CUSTODY_MODE, runMode);
|
|
2866
2916
|
if (!ownerSessionToken) {
|
|
2867
2917
|
throw createCliError('LOGIN_EMAIL_OWNER_SESSION_MISSING', 'Email onboarding completed without an owner session token.');
|
|
@@ -3590,6 +3640,15 @@ function buildBuildTxPayload(flags, resolvedAction) {
|
|
|
3590
3640
|
return payload;
|
|
3591
3641
|
}
|
|
3592
3642
|
|
|
3643
|
+
function resolveEffectiveUserDid(flags) {
|
|
3644
|
+
const explicit = String(flags.userDid || '').trim();
|
|
3645
|
+
if (explicit) return explicit;
|
|
3646
|
+
const envUserDid = String(process.env.THIRDFY_USER_DID || '').trim();
|
|
3647
|
+
if (envUserDid) return envUserDid;
|
|
3648
|
+
const config = loadProfileConfig();
|
|
3649
|
+
return String(config?.wallets?.userDid || config?.identity?.userDid || '').trim();
|
|
3650
|
+
}
|
|
3651
|
+
|
|
3593
3652
|
function buildManagedExecutePayload(flags, options) {
|
|
3594
3653
|
const runMode = String(options.runMode || flags.runMode || 'agent_wallet').trim().toLowerCase();
|
|
3595
3654
|
const params = getPreparedParams(flags);
|
|
@@ -3620,7 +3679,7 @@ function buildManagedExecutePayload(flags, options) {
|
|
|
3620
3679
|
const payload = {
|
|
3621
3680
|
agentApiKey: resolveAgentApiKey(flags, runMode),
|
|
3622
3681
|
action: String(options.resolvedAction || requireFlag(flags, 'action', 'Missing --action')).trim(),
|
|
3623
|
-
userDid:
|
|
3682
|
+
userDid: resolveEffectiveUserDid(flags),
|
|
3624
3683
|
params: managedParams,
|
|
3625
3684
|
chainId: Number(flags.chainId || 8453),
|
|
3626
3685
|
executionStrategy: {
|
|
@@ -3631,7 +3690,7 @@ function buildManagedExecutePayload(flags, options) {
|
|
|
3631
3690
|
if (!payload.userDid) {
|
|
3632
3691
|
throw createCliError(
|
|
3633
3692
|
'MISSING_USER_DID',
|
|
3634
|
-
'Managed wallet execution requires --user-did
|
|
3693
|
+
'Managed wallet execution requires --user-did, THIRDFY_USER_DID, or a saved userDid from `thirdfy-agent login email`.'
|
|
3635
3694
|
);
|
|
3636
3695
|
}
|
|
3637
3696
|
if (flags.estimatedAmountUsd) payload.estimatedAmountUsd = Number(flags.estimatedAmountUsd);
|
|
@@ -3655,13 +3714,13 @@ async function resolveManagedExecutionPreflight(ctx, flags, resolved, options =
|
|
|
3655
3714
|
const chainId = Number(flags.chainId || 8453);
|
|
3656
3715
|
const runMode = String(options.runMode || 'agent_wallet').trim().toLowerCase();
|
|
3657
3716
|
const agentApiKey = resolveAgentApiKey(flags, runMode);
|
|
3658
|
-
const userDid =
|
|
3717
|
+
const userDid = resolveEffectiveUserDid(flags);
|
|
3659
3718
|
if (!userDid) {
|
|
3660
3719
|
return {
|
|
3661
3720
|
success: false,
|
|
3662
3721
|
blockedReason: 'MISSING_USER_DID',
|
|
3663
3722
|
blockedStage: 'routing',
|
|
3664
|
-
error: 'Managed wallet execution requires --user-did
|
|
3723
|
+
error: 'Managed wallet execution requires --user-did, THIRDFY_USER_DID, or a saved userDid from `thirdfy-agent login email`.',
|
|
3665
3724
|
signerMethod: 'managed_wallet_server',
|
|
3666
3725
|
};
|
|
3667
3726
|
}
|
|
@@ -3742,8 +3801,16 @@ function buildIntentPayload(flags, options) {
|
|
|
3742
3801
|
if (flags.catalog) payload.catalog = String(flags.catalog).trim();
|
|
3743
3802
|
if (flags.chainId) payload.chainId = Number(flags.chainId);
|
|
3744
3803
|
if (flags.estimatedAmountUsd) payload.estimatedAmountUsd = Number(flags.estimatedAmountUsd);
|
|
3745
|
-
|
|
3804
|
+
const userDid = resolveEffectiveUserDid(flags);
|
|
3805
|
+
if (flags.userDid || (options.validationOnly && (runMode === 'agent_wallet' || (runMode === 'hybrid' && options.mirrorOnly)))) {
|
|
3806
|
+
if (userDid) payload.userDid = userDid;
|
|
3807
|
+
}
|
|
3746
3808
|
if (options.validationOnly) payload.executionLane = 'validation_only';
|
|
3809
|
+
if (flags.executionScope) {
|
|
3810
|
+
payload.executionScope = String(flags.executionScope).trim();
|
|
3811
|
+
} else if (options.validationOnly && (runMode === 'agent_wallet' || (runMode === 'hybrid' && options.mirrorOnly))) {
|
|
3812
|
+
payload.executionScope = 'solo_owner_mirror';
|
|
3813
|
+
}
|
|
3747
3814
|
if (options.runMode) {
|
|
3748
3815
|
payload.executionStrategy = {
|
|
3749
3816
|
runMode: String(options.runMode),
|