@thirdfy/agent-cli 0.1.24 → 0.1.27
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 +54 -0
- package/README.md +3 -1
- package/bin/thirdfy-agent.mjs +233 -18
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,60 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`npm run publish:npm:local`** (`scripts/local-npm-publish.sh`): loads gitignored `.env`, exports `NODE_AUTH_TOKEN` from `NPM_TOKEN`, then runs `release:npm` via **node** (`scripts/release-npm.mjs`, `--dry-run` or `--publish`) so the outer `npm run` does not strip registry auth before the release script runs. Documented in `docs/releasing.md` Path B.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- `release:npm`: `npm publish` now uses a short-lived `NPM_CONFIG_USERCONFIG` file with `//registry.npmjs.org/:_authToken=…` when a token is present, so npm 10+ authenticates reliably (Bearer env alone was not enough in this repo’s CLI runs).
|
|
14
|
+
- `release:npm -- --publish`: when both `NODE_AUTH_TOKEN` and `NPM_TOKEN` are set but `NODE_AUTH_TOKEN` is much shorter than `NPM_TOKEN` (common placeholder), use `NPM_TOKEN` for the publish subprocess and print a warning.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **CI:** Release workflow no longer requests `id-token: write` (npm publish uses `secrets.NPM_TOKEN` only).
|
|
19
|
+
|
|
20
|
+
## [0.1.27] - 2026-05-05
|
|
21
|
+
|
|
22
|
+
**npm:** [`@thirdfy/agent-cli@0.1.27`](https://www.npmjs.com/package/@thirdfy/agent-cli/v/0.1.27)
|
|
23
|
+
**Git tag:** [`v0.1.27`](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.27)
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Maintainer [docs/releasing.md](./docs/releasing.md) runbook for npm + GitHub Actions, `.env.example` template, and `npm run release:npm` (`scripts/release-npm.mjs`) with dry-run default and stricter checks for `--publish`.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **Bugbot (PR #24):** `release:npm` maps `NPM_TOKEN` → `NODE_AUTH_TOKEN` for the publish subprocess; `npm publish` uses `--ignore-scripts` after explicit checks so `prepublishOnly` does not run twice. **Release** GitHub Action uses the same `npm publish --ignore-scripts` after its validation steps.
|
|
32
|
+
|
|
33
|
+
## [0.1.26] - 2026-05-05
|
|
34
|
+
|
|
35
|
+
**Git tag:** [`v0.1.26`](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.26) — provider parity merged to `main`; not published to the npm registry (use **0.1.27** for the first npm build that includes PR #23 plus release tooling from PR #24).
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- **Provider discovery parity:** Align `actions --provider` filtering with MCP/API provider taxonomy for provider-less spot, Hyperliquid/perps, bridge, DogeOS, prediction, and earn catalog rows.
|
|
40
|
+
- **Metadata-first discovery:** Prefer API-supplied `providerId`, `domain`, and `category` for provider filtering, keeping action-name inference as a legacy fallback only.
|
|
41
|
+
- **Bugbot:** `actions --provider` key fallback now matches provider suffix patterns (e.g. `execute_bridge` for `--provider bridge`).
|
|
42
|
+
- **Bugbot:** After metadata mismatch, hyperliquid/polymarket/bridge/DogeOS branches use action-key matching only (removed redundant `provider ===` checks and dead final equality).
|
|
43
|
+
|
|
44
|
+
## [0.1.25] - 2026-05-04
|
|
45
|
+
|
|
46
|
+
**npm:** [`@thirdfy/agent-cli@0.1.25`](https://www.npmjs.com/package/@thirdfy/agent-cli/v/0.1.25)
|
|
47
|
+
**Git tag:** [`v0.1.25`](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.25)
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- **Capabilities negotiation:** Cache negotiated Thirdfy CLI capabilities and derive provider hints from the live API response to reduce static hint drift.
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- **Managed wallet payloads:** Align swap and related `params` with human-readable amount fields expected by the Thirdfy API when using `amountInHuman`.
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
|
|
59
|
+
- **Tests:** `test/managed-wallet-payload.test.cjs` for managed-wallet payload shape.
|
|
60
|
+
|
|
7
61
|
## [0.1.24] - 2026-05-02
|
|
8
62
|
|
|
9
63
|
**npm:** [`@thirdfy/agent-cli@0.1.24`](https://www.npmjs.com/package/@thirdfy/agent-cli/v/0.1.24)
|
package/README.md
CHANGED
|
@@ -40,7 +40,9 @@ npx @thirdfy/agent-cli --help
|
|
|
40
40
|
|
|
41
41
|
## Release notes
|
|
42
42
|
|
|
43
|
-
Version history and highlights: [CHANGELOG.md](./CHANGELOG.md). Recent CLI releases document
|
|
43
|
+
Version history and highlights: [CHANGELOG.md](./CHANGELOG.md). Recent CLI releases document provider discovery parity, metadata-first `actions --provider` filtering, earn deposit guards, and README refresh through **v0.1.27**.
|
|
44
|
+
|
|
45
|
+
**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.
|
|
44
46
|
|
|
45
47
|
## Quick start
|
|
46
48
|
|
package/bin/thirdfy-agent.mjs
CHANGED
|
@@ -27,6 +27,7 @@ const RUN_MODES = ['thirdfy', 'self', 'hybrid', 'agent_wallet'];
|
|
|
27
27
|
const HYBRID_WALLET_MODES = ['self', 'agent_wallet'];
|
|
28
28
|
const CUSTODY_MODES = ['managed', 'external'];
|
|
29
29
|
const EFFECT_CHECK_MODES = ['strict', 'relaxed', 'off'];
|
|
30
|
+
let negotiatedCapabilitiesCache = null;
|
|
30
31
|
const PROFILE_DEFAULTS = {
|
|
31
32
|
personal: 'self',
|
|
32
33
|
builder: 'hybrid',
|
|
@@ -153,6 +154,7 @@ async function main() {
|
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
const capabilities = await negotiateCapabilities(context);
|
|
157
|
+
negotiatedCapabilitiesCache = capabilities;
|
|
156
158
|
|
|
157
159
|
switch (commandKey) {
|
|
158
160
|
case 'agent run':
|
|
@@ -556,8 +558,57 @@ function getTradingProviderHint(providerId) {
|
|
|
556
558
|
return null;
|
|
557
559
|
}
|
|
558
560
|
|
|
559
|
-
function getCachedProviderHintFromCapabilities(
|
|
560
|
-
|
|
561
|
+
function getCachedProviderHintFromCapabilities(provider) {
|
|
562
|
+
const normalizedProvider = String(provider || '').trim().toLowerCase();
|
|
563
|
+
if (!normalizedProvider) return null;
|
|
564
|
+
const manifests = Array.isArray(negotiatedCapabilitiesCache?.providers?.manifests)
|
|
565
|
+
? negotiatedCapabilitiesCache.providers.manifests
|
|
566
|
+
: [];
|
|
567
|
+
const match = manifests.find((entry) => String(entry?.providerId || '').trim().toLowerCase() === normalizedProvider);
|
|
568
|
+
if (!match) return null;
|
|
569
|
+
const canonicalWriteActions = {
|
|
570
|
+
trading: 'swap',
|
|
571
|
+
hyperliquid: 'place_hyperliquid_perps_order',
|
|
572
|
+
polymarket: 'place_polymarket_order',
|
|
573
|
+
prediction: 'place_prediction_order',
|
|
574
|
+
earn: 'deposit_earn_position',
|
|
575
|
+
morpho: 'deposit_earn_position',
|
|
576
|
+
curve: 'deposit_earn_position',
|
|
577
|
+
};
|
|
578
|
+
const canonicalReadActions = {
|
|
579
|
+
earn: 'get_earn_opportunities',
|
|
580
|
+
morpho: 'get_morpho_vaults',
|
|
581
|
+
curve: 'get_curve_pools',
|
|
582
|
+
prediction: 'get_prediction_markets',
|
|
583
|
+
};
|
|
584
|
+
return {
|
|
585
|
+
provider: normalizedProvider,
|
|
586
|
+
category: match.category || match.domain || match.providerKind || null,
|
|
587
|
+
...(canonicalReadActions[normalizedProvider] ? { canonicalReadAction: canonicalReadActions[normalizedProvider] } : {}),
|
|
588
|
+
...(canonicalWriteActions[normalizedProvider] ? { canonicalWriteAction: canonicalWriteActions[normalizedProvider] } : {}),
|
|
589
|
+
providerKind: match.providerKind || null,
|
|
590
|
+
capabilities: Array.isArray(match.capabilities) ? match.capabilities : [],
|
|
591
|
+
supportedChains: Array.isArray(match.supportedChains) ? match.supportedChains : [],
|
|
592
|
+
custodyMode: match.custodyMode || null,
|
|
593
|
+
description: match.description || null,
|
|
594
|
+
source: 'cli_capabilities_manifest',
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
function formatProviderAmbiguousActionHint(providerHint) {
|
|
599
|
+
if (!providerHint) return '';
|
|
600
|
+
const p = providerHint.provider;
|
|
601
|
+
const w = providerHint.canonicalWriteAction;
|
|
602
|
+
if (w) return ` Provider ${p} expects ${w}.`;
|
|
603
|
+
return ` Provider ${p} did not declare a canonical write action in capabilities; run actions --provider ${p} first.`;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
function formatProviderUnknownActionHint(providerHint) {
|
|
607
|
+
if (!providerHint) return '';
|
|
608
|
+
const p = providerHint.provider;
|
|
609
|
+
const w = providerHint.canonicalWriteAction;
|
|
610
|
+
if (w) return ` Provider ${p} expects ${w}; run actions --provider ${p} first.`;
|
|
611
|
+
return ` Provider ${p} did not declare a canonical write action in capabilities; run actions --provider ${p} first.`;
|
|
561
612
|
}
|
|
562
613
|
|
|
563
614
|
const OFFCHAIN_VENUE_ORDER_ACTIONS = new Set([
|
|
@@ -2966,11 +3017,16 @@ function buildBuildTxPayload(flags, resolvedAction) {
|
|
|
2966
3017
|
|
|
2967
3018
|
function buildManagedExecutePayload(flags, options) {
|
|
2968
3019
|
const runMode = String(options.runMode || flags.runMode || 'agent_wallet').trim().toLowerCase();
|
|
3020
|
+
const params = getPreparedParams(flags);
|
|
3021
|
+
const managedParams = { ...params };
|
|
3022
|
+
if (flags.__swapInput?.unitSource === 'human' && flags.__swapInput.amountInHuman) {
|
|
3023
|
+
managedParams.amountIn = flags.__swapInput.amountInHuman;
|
|
3024
|
+
}
|
|
2969
3025
|
const payload = {
|
|
2970
3026
|
agentApiKey: resolveAgentApiKey(flags, runMode),
|
|
2971
3027
|
action: String(options.resolvedAction || requireFlag(flags, 'action', 'Missing --action')).trim(),
|
|
2972
3028
|
userDid: String(flags.userDid || process.env.THIRDFY_USER_DID || '').trim(),
|
|
2973
|
-
params:
|
|
3029
|
+
params: managedParams,
|
|
2974
3030
|
chainId: Number(flags.chainId || 8453),
|
|
2975
3031
|
executionStrategy: {
|
|
2976
3032
|
runMode,
|
|
@@ -3172,6 +3228,172 @@ function formatActionList(items) {
|
|
|
3172
3228
|
.join(', ');
|
|
3173
3229
|
}
|
|
3174
3230
|
|
|
3231
|
+
function normalizeProviderId(value) {
|
|
3232
|
+
return String(value || '').trim().toLowerCase();
|
|
3233
|
+
}
|
|
3234
|
+
|
|
3235
|
+
function rowActionKey(action) {
|
|
3236
|
+
return getActionKey(action)
|
|
3237
|
+
.replace(/-/g, '_')
|
|
3238
|
+
.toLowerCase();
|
|
3239
|
+
}
|
|
3240
|
+
|
|
3241
|
+
function canonicalActionKey(action) {
|
|
3242
|
+
return getActionKey(action)
|
|
3243
|
+
.replace(/_/g, '-')
|
|
3244
|
+
.toLowerCase();
|
|
3245
|
+
}
|
|
3246
|
+
|
|
3247
|
+
function inferActionProvider(action) {
|
|
3248
|
+
// API catalog metadata (`providerId`, `domain`, `category`) is the source of truth.
|
|
3249
|
+
// This fallback only keeps older catalog rows / older API deployments discoverable.
|
|
3250
|
+
const key = canonicalActionKey(action);
|
|
3251
|
+
const knownMap = {
|
|
3252
|
+
swap: 'trading',
|
|
3253
|
+
'execute-optimal-swap': 'trading',
|
|
3254
|
+
'get-best-trading-quote': 'trading',
|
|
3255
|
+
'dogeos-barkswap-get-quote': 'dogeos-barkswap',
|
|
3256
|
+
'dogeos-barkswap-execute-swap': 'dogeos-barkswap',
|
|
3257
|
+
'dogeos-get-ecosystem-overview': 'dogeos-ecosystem',
|
|
3258
|
+
'dogeos-get-wallet-actionability': 'dogeos-ecosystem',
|
|
3259
|
+
'dogeos-prepare-trade': 'dogeos-ecosystem',
|
|
3260
|
+
'dogeos-prepare-token-launch': 'dogeos-ecosystem',
|
|
3261
|
+
'dogeos-get-chain-insights': 'dogeos-ecosystem',
|
|
3262
|
+
'dogeos-get-trending-tokens': 'dogeos-ecosystem',
|
|
3263
|
+
'dogeos-get-new-tokens': 'dogeos-ecosystem',
|
|
3264
|
+
'dogeos-get-early-bird-tokens': 'dogeos-ecosystem',
|
|
3265
|
+
'dogeos-get-only-moon-tokens': 'dogeos-ecosystem',
|
|
3266
|
+
'dogeos-get-big-wins-tokens': 'dogeos-ecosystem',
|
|
3267
|
+
'dogeos-get-related-tokens': 'dogeos-ecosystem',
|
|
3268
|
+
'dogeos-laika-read-contract': 'dogeos-laika',
|
|
3269
|
+
'dogeos-laika-execute-raw': 'dogeos-laika',
|
|
3270
|
+
'dogeos-laika-launch-token': 'dogeos-laika',
|
|
3271
|
+
'dogeos-laika-buy-token': 'dogeos-laika',
|
|
3272
|
+
'dogeos-laika-claim': 'dogeos-laika',
|
|
3273
|
+
'dogeos-laika-token-state': 'dogeos-laika',
|
|
3274
|
+
'get-governance-v2-overview': 'governance-v2',
|
|
3275
|
+
'get-governance-v2-timeseries': 'governance-v2',
|
|
3276
|
+
'get-governance-v2-breakdowns': 'governance-v2',
|
|
3277
|
+
'get-hyperliquid-perps-meta': 'hyperliquid',
|
|
3278
|
+
'get-hyperliquid-all-mids': 'hyperliquid',
|
|
3279
|
+
'get-hyperliquid-l2-book': 'hyperliquid',
|
|
3280
|
+
'get-hyperliquid-candles': 'hyperliquid',
|
|
3281
|
+
'get-hyperliquid-user-state': 'hyperliquid',
|
|
3282
|
+
'get-hyperliquid-open-orders': 'hyperliquid',
|
|
3283
|
+
'get-hyperliquid-setup-status': 'hyperliquid',
|
|
3284
|
+
'get-hyperliquid-onboarding-plan': 'hyperliquid',
|
|
3285
|
+
'prepare-hyperliquid-onboarding': 'hyperliquid',
|
|
3286
|
+
'claim-hyperliquid-testnet-faucet': 'hyperliquid',
|
|
3287
|
+
'get-hyperliquid-builder-fee-status': 'hyperliquid',
|
|
3288
|
+
'approve-hyperliquid-agent': 'hyperliquid',
|
|
3289
|
+
'approve-hyperliquid-builder-fee': 'hyperliquid',
|
|
3290
|
+
'register-hyperliquid-referrer': 'hyperliquid',
|
|
3291
|
+
'set-hyperliquid-referrer': 'hyperliquid',
|
|
3292
|
+
'get-hyperliquid-referral-status': 'hyperliquid',
|
|
3293
|
+
'deposit-hyperliquid-staking': 'hyperliquid',
|
|
3294
|
+
'deposit-hyperliquid-bridge': 'hyperliquid',
|
|
3295
|
+
'place-hyperliquid-perps-order': 'hyperliquid',
|
|
3296
|
+
'get-perps-markets': 'hyperliquid',
|
|
3297
|
+
'get-perps-account': 'hyperliquid',
|
|
3298
|
+
'get-perps-position': 'hyperliquid',
|
|
3299
|
+
'place-perps-order': 'hyperliquid',
|
|
3300
|
+
'cancel-perps-order': 'hyperliquid',
|
|
3301
|
+
'get-earn-opportunities': 'earn',
|
|
3302
|
+
'get-earn-provider': 'earn',
|
|
3303
|
+
'get-earn-position': 'earn',
|
|
3304
|
+
'deposit-earn-position': 'earn',
|
|
3305
|
+
'withdraw-earn-position': 'earn',
|
|
3306
|
+
'get-morpho-vaults': 'morpho',
|
|
3307
|
+
'deposit-morpho-vault': 'morpho',
|
|
3308
|
+
'withdraw-morpho-vault': 'morpho',
|
|
3309
|
+
'get-curve-pools': 'curve',
|
|
3310
|
+
'get-curve-pool-details': 'curve',
|
|
3311
|
+
'deposit-curve-pool': 'curve',
|
|
3312
|
+
'withdraw-curve-pool': 'curve',
|
|
3313
|
+
'get-prediction-markets': 'polymarket',
|
|
3314
|
+
'get-prediction-market': 'polymarket',
|
|
3315
|
+
'get-prediction-order-book': 'polymarket',
|
|
3316
|
+
'get-prediction-position': 'polymarket',
|
|
3317
|
+
'place-prediction-order': 'polymarket',
|
|
3318
|
+
'cancel-prediction-order': 'polymarket',
|
|
3319
|
+
'get-polymarket-markets': 'polymarket',
|
|
3320
|
+
'get-polymarket-market': 'polymarket',
|
|
3321
|
+
'get-polymarket-setup-status': 'polymarket',
|
|
3322
|
+
'get-polymarket-order': 'polymarket',
|
|
3323
|
+
'place-polymarket-order': 'polymarket',
|
|
3324
|
+
};
|
|
3325
|
+
if (knownMap[key]) return knownMap[key];
|
|
3326
|
+
if (key.includes('hyperliquid')) return 'hyperliquid';
|
|
3327
|
+
if (key.includes('polymarket') || key.includes('prediction')) return 'polymarket';
|
|
3328
|
+
if (key.includes('morpho')) return 'morpho';
|
|
3329
|
+
if (key.includes('curve')) return 'curve';
|
|
3330
|
+
if (key.includes('earn')) return 'earn';
|
|
3331
|
+
if (key.includes('bridge')) return 'bridge';
|
|
3332
|
+
if (key.includes('dogeos-barkswap')) return 'dogeos-barkswap';
|
|
3333
|
+
if (key.includes('dogeos-laika')) return 'dogeos-laika';
|
|
3334
|
+
if (key.includes('dogeos')) return 'dogeos-ecosystem';
|
|
3335
|
+
return '';
|
|
3336
|
+
}
|
|
3337
|
+
|
|
3338
|
+
function getActionProviderWithInference(action) {
|
|
3339
|
+
return getActionProvider(action) || inferActionProvider(action);
|
|
3340
|
+
}
|
|
3341
|
+
|
|
3342
|
+
function isEarnCatalogAction(action) {
|
|
3343
|
+
const actionKey = rowActionKey(action);
|
|
3344
|
+
return (
|
|
3345
|
+
actionKey.includes('_earn_') ||
|
|
3346
|
+
normalizeProviderId(action?.domain) === 'earn' ||
|
|
3347
|
+
normalizeProviderId(action?.category) === 'earn'
|
|
3348
|
+
);
|
|
3349
|
+
}
|
|
3350
|
+
|
|
3351
|
+
function isSpotTradingCatalogAction(action) {
|
|
3352
|
+
const actionKey = rowActionKey(action);
|
|
3353
|
+
return actionKey === 'swap' || actionKey === 'execute_optimal_swap' || actionKey === 'get_best_trading_quote';
|
|
3354
|
+
}
|
|
3355
|
+
|
|
3356
|
+
function isProviderActionKey(action, provider) {
|
|
3357
|
+
const actionKey = rowActionKey(action);
|
|
3358
|
+
const normalizedProvider = normalizeProviderId(provider).replace(/-/g, '_');
|
|
3359
|
+
if (!actionKey || !normalizedProvider) return false;
|
|
3360
|
+
return (
|
|
3361
|
+
actionKey === normalizedProvider ||
|
|
3362
|
+
actionKey.startsWith(`${normalizedProvider}_`) ||
|
|
3363
|
+
actionKey.includes(`_${normalizedProvider}_`) ||
|
|
3364
|
+
actionKey.endsWith(`_${normalizedProvider}`)
|
|
3365
|
+
);
|
|
3366
|
+
}
|
|
3367
|
+
|
|
3368
|
+
function actionMatchesProvider(action, requestedProvider, allActions) {
|
|
3369
|
+
const provider = getActionProviderWithInference(action);
|
|
3370
|
+
const actionKey = rowActionKey(action);
|
|
3371
|
+
if (provider === requestedProvider) return true;
|
|
3372
|
+
if (requestedProvider === 'trading') return isSpotTradingCatalogAction(action);
|
|
3373
|
+
// Here resolved metadata already disagrees with the filter; fall back to action-key shape only.
|
|
3374
|
+
if (requestedProvider === 'hyperliquid') return isProviderActionKey(action, 'hyperliquid');
|
|
3375
|
+
if (requestedProvider === 'polymarket') return isProviderActionKey(action, 'polymarket');
|
|
3376
|
+
if (requestedProvider === 'bridge') return isProviderActionKey(action, 'bridge');
|
|
3377
|
+
if (requestedProvider.startsWith('dogeos')) return isProviderActionKey(action, requestedProvider);
|
|
3378
|
+
if (requestedProvider === 'earn') {
|
|
3379
|
+
return provider === 'earn' || provider === 'morpho' || provider === 'curve' || isEarnCatalogAction(action);
|
|
3380
|
+
}
|
|
3381
|
+
if (requestedProvider === 'morpho' || requestedProvider === 'curve') {
|
|
3382
|
+
const hasProtocolSpecificEarnRows = allActions.some((candidate) => getActionProviderWithInference(candidate) === requestedProvider);
|
|
3383
|
+
return isProviderActionKey(action, requestedProvider) || (!hasProtocolSpecificEarnRows && isEarnCatalogAction(action));
|
|
3384
|
+
}
|
|
3385
|
+
if (requestedProvider === 'prediction') {
|
|
3386
|
+
return (
|
|
3387
|
+
provider === 'polymarket' ||
|
|
3388
|
+
provider === 'prediction' ||
|
|
3389
|
+
actionKey.includes('_prediction_') ||
|
|
3390
|
+
normalizeProviderId(action?.domain) === 'prediction' ||
|
|
3391
|
+
normalizeProviderId(action?.category) === 'prediction'
|
|
3392
|
+
);
|
|
3393
|
+
}
|
|
3394
|
+
return isProviderActionKey(action, requestedProvider);
|
|
3395
|
+
}
|
|
3396
|
+
|
|
3175
3397
|
function applyActionFilters(actions, flags) {
|
|
3176
3398
|
let filtered = actions;
|
|
3177
3399
|
if (flags.catalog) {
|
|
@@ -3179,21 +3401,14 @@ function applyActionFilters(actions, flags) {
|
|
|
3179
3401
|
filtered = filtered.filter((a) => String(a.catalog || a.catalogId || 'default').trim().toLowerCase() === expectedCatalog);
|
|
3180
3402
|
}
|
|
3181
3403
|
if (flags.provider) {
|
|
3182
|
-
const expectedProvider =
|
|
3183
|
-
filtered = filtered.filter((a) =>
|
|
3184
|
-
const provider = getActionProvider(a);
|
|
3185
|
-
const actionKey = getActionKey(a).replace(/-/g, '_').toLowerCase();
|
|
3186
|
-
if (provider === expectedProvider) return true;
|
|
3187
|
-
if (expectedProvider === 'earn') return provider === 'morpho' || provider === 'curve' || actionKey.includes('_earn_');
|
|
3188
|
-
if (expectedProvider === 'prediction') return provider === 'polymarket' || actionKey.includes('_prediction_');
|
|
3189
|
-
return false;
|
|
3190
|
-
});
|
|
3404
|
+
const expectedProvider = normalizeProviderId(flags.provider);
|
|
3405
|
+
filtered = filtered.filter((a) => actionMatchesProvider(a, expectedProvider, filtered));
|
|
3191
3406
|
}
|
|
3192
3407
|
return filtered;
|
|
3193
3408
|
}
|
|
3194
3409
|
|
|
3195
3410
|
function getActionProvider(action) {
|
|
3196
|
-
return
|
|
3411
|
+
return normalizeProviderId(action?.provider || action?.providerId || action?.provider_id || action?.catalog || '');
|
|
3197
3412
|
}
|
|
3198
3413
|
|
|
3199
3414
|
async function resolveActionSelection(ctx, flags) {
|
|
@@ -3235,7 +3450,7 @@ async function resolveActionSelection(ctx, flags) {
|
|
|
3235
3450
|
throw new Error(
|
|
3236
3451
|
`Ambiguous --action "${requestedAction}". Alias matches multiple actions: ${formatActionList(
|
|
3237
3452
|
exactAlias.map((v) => v.key)
|
|
3238
|
-
)}.${providerHint
|
|
3453
|
+
)}.${formatProviderAmbiguousActionHint(providerHint)}`
|
|
3239
3454
|
);
|
|
3240
3455
|
}
|
|
3241
3456
|
|
|
@@ -3252,14 +3467,14 @@ async function resolveActionSelection(ctx, flags) {
|
|
|
3252
3467
|
throw new Error(
|
|
3253
3468
|
`Ambiguous --action "${requestedAction}". Did you mean one of: ${formatActionList(
|
|
3254
3469
|
fuzzy.slice(0, 10).map((v) => v.key)
|
|
3255
|
-
)}?${providerHint
|
|
3470
|
+
)}?${formatProviderAmbiguousActionHint(providerHint)}`
|
|
3256
3471
|
);
|
|
3257
3472
|
}
|
|
3258
3473
|
const providerHint = flags.provider ? getTradingProviderHint(flags.provider) : null;
|
|
3259
3474
|
throw new Error(
|
|
3260
|
-
`Unknown --action "${requestedAction}". No compatible action found in current catalog/provider scope.${
|
|
3261
|
-
providerHint
|
|
3262
|
-
}`
|
|
3475
|
+
`Unknown --action "${requestedAction}". No compatible action found in current catalog/provider scope.${formatProviderUnknownActionHint(
|
|
3476
|
+
providerHint
|
|
3477
|
+
)}`
|
|
3263
3478
|
);
|
|
3264
3479
|
}
|
|
3265
3480
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thirdfy/agent-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "Thirdfy Agent CLI for onboarding, governance preflight, execute-intent, and status polling.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
"scripts": {
|
|
19
19
|
"test": "node --test \"test/**/*.test.cjs\"",
|
|
20
20
|
"lint": "node --check ./bin/thirdfy-agent.mjs",
|
|
21
|
+
"release:npm": "node ./scripts/release-npm.mjs",
|
|
22
|
+
"publish:npm:local": "bash ./scripts/local-npm-publish.sh",
|
|
21
23
|
"validate:public-docs": "node ./scripts/validate-public-docs.mjs",
|
|
22
24
|
"validate:cli-contract-schemas": "node ./scripts/validate-cli-contract-schemas.mjs",
|
|
23
25
|
"validate:actions": "node ./scripts/e2e/validate-actions.mjs",
|