@thirdfy/agent-cli 0.1.25 → 0.1.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 +45 -1
- package/README.md +3 -1
- package/bin/thirdfy-agent.mjs +246 -16
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,9 +4,53 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.28] - 2026-05-05
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `thirdfy-agent analytics portfolio` for API-owned agent portfolio NAV, principal, PnL, ROI, APR, holdings, and confidence reads.
|
|
12
|
+
- `thirdfy-agent analytics leaderboard` for category/network/window-ranked agent performance across `trading`, `yield`, and `prediction`.
|
|
13
|
+
- **`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.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- `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).
|
|
18
|
+
- `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.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Refactored portfolio-related read commands to share query-param and `meta` construction (`applySharedPortfolioListingFiltersToQuery`, `buildAgentKeyPortfolioSummaryQuery`, `metaPortfolioListingFilters`) so telemetry summary and portfolio summary stay aligned.
|
|
23
|
+
- Documented portfolio analytics commands as read-only CLI surfaces over Thirdfy API accounting.
|
|
24
|
+
- **CI:** Release workflow no longer requests `id-token: write` (npm publish uses `secrets.NPM_TOKEN` only).
|
|
25
|
+
|
|
26
|
+
## [0.1.27] - 2026-05-05
|
|
27
|
+
|
|
28
|
+
**npm:** [`@thirdfy/agent-cli@0.1.27`](https://www.npmjs.com/package/@thirdfy/agent-cli/v/0.1.27)
|
|
29
|
+
**Git tag:** [`v0.1.27`](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.27)
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- 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`.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- **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.
|
|
38
|
+
|
|
39
|
+
## [0.1.26] - 2026-05-05
|
|
40
|
+
|
|
41
|
+
**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).
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- **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.
|
|
46
|
+
- **Metadata-first discovery:** Prefer API-supplied `providerId`, `domain`, and `category` for provider filtering, keeping action-name inference as a legacy fallback only.
|
|
47
|
+
- **Bugbot:** `actions --provider` key fallback now matches provider suffix patterns (e.g. `execute_bridge` for `--provider bridge`).
|
|
48
|
+
- **Bugbot:** After metadata mismatch, hyperliquid/polymarket/bridge/DogeOS branches use action-key matching only (removed redundant `provider ===` checks and dead final equality).
|
|
49
|
+
|
|
7
50
|
## [0.1.25] - 2026-05-04
|
|
8
51
|
|
|
9
|
-
**npm:** `@thirdfy/agent-cli@0.1.25`
|
|
52
|
+
**npm:** [`@thirdfy/agent-cli@0.1.25`](https://www.npmjs.com/package/@thirdfy/agent-cli/v/0.1.25)
|
|
53
|
+
**Git tag:** [`v0.1.25`](https://github.com/thirdfy/agent-cli/releases/tag/v0.1.25)
|
|
10
54
|
|
|
11
55
|
### Changed
|
|
12
56
|
|
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, portfolio analytics commands, and README refresh through **v0.1.28**.
|
|
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
|
@@ -279,6 +279,14 @@ async function main() {
|
|
|
279
279
|
await commandWalletSubmit(context, subFlags, capabilities);
|
|
280
280
|
return;
|
|
281
281
|
}
|
|
282
|
+
if (commandKey3 === 'analytics portfolio') {
|
|
283
|
+
await commandAnalyticsPortfolio(context, subFlags, capabilities);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (commandKey3 === 'analytics leaderboard') {
|
|
287
|
+
await commandAnalyticsLeaderboard(context, subFlags, capabilities);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
282
290
|
|
|
283
291
|
const rootCommand = parsed.positionals[0];
|
|
284
292
|
switch (rootCommand) {
|
|
@@ -808,21 +816,82 @@ async function commandCatalogsList(ctx, flags, capabilities) {
|
|
|
808
816
|
});
|
|
809
817
|
}
|
|
810
818
|
|
|
811
|
-
|
|
819
|
+
/** Query params shared by telemetry summary and portfolio summary (`agentKey` + scope filters). */
|
|
820
|
+
function applySharedPortfolioListingFiltersToQuery(query, flags) {
|
|
821
|
+
if (flags.chainId) query.set('chainId', String(flags.chainId));
|
|
822
|
+
if (flags.network) query.set('networkId', String(flags.network));
|
|
823
|
+
if (flags.networkId) query.set('networkId', String(flags.networkId));
|
|
824
|
+
if (flags.chainType) query.set('chainType', String(flags.chainType));
|
|
825
|
+
if (flags.category) query.set('category', String(flags.category));
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
function buildAgentKeyPortfolioSummaryQuery(flags, { includeLimit = false } = {}) {
|
|
812
829
|
const agentKey = requireFlag(flags, 'agentKey', 'Missing --agent-key');
|
|
813
830
|
const query = new URLSearchParams({ agentKey });
|
|
814
|
-
|
|
815
|
-
if (flags.limit) query.set('limit', String(flags.limit));
|
|
831
|
+
applySharedPortfolioListingFiltersToQuery(query, flags);
|
|
832
|
+
if (includeLimit && flags.limit) query.set('limit', String(flags.limit));
|
|
833
|
+
return { agentKey, query };
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/** `meta` fields that echo portfolio scope filters (keep in sync with query construction). */
|
|
837
|
+
function metaPortfolioListingFilters(ctx, flags, capabilities, agentKey) {
|
|
838
|
+
return {
|
|
839
|
+
apiBase: ctx.apiBase,
|
|
840
|
+
agentKey,
|
|
841
|
+
chainId: flags.chainId ? Number(flags.chainId) : null,
|
|
842
|
+
networkId: flags.networkId || flags.network || null,
|
|
843
|
+
chainType: flags.chainType || null,
|
|
844
|
+
category: flags.category || null,
|
|
845
|
+
capabilitiesVersion: capabilities?.contractVersion || null,
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
async function commandDataSummary(ctx, flags, capabilities) {
|
|
850
|
+
const { agentKey, query } = buildAgentKeyPortfolioSummaryQuery(flags, { includeLimit: true });
|
|
816
851
|
const response = await apiGet(ctx, `/api/v1/agent/telemetry/summary?${query.toString()}`);
|
|
817
852
|
printEnvelope({
|
|
818
853
|
success: true,
|
|
819
854
|
code: 'DATA_SUMMARY_OK',
|
|
820
855
|
message: 'Agent data summary loaded',
|
|
821
856
|
data: response,
|
|
857
|
+
meta: metaPortfolioListingFilters(ctx, flags, capabilities, agentKey),
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
async function commandAnalyticsPortfolio(ctx, flags, capabilities) {
|
|
862
|
+
const { agentKey, query } = buildAgentKeyPortfolioSummaryQuery(flags);
|
|
863
|
+
const response = await apiGet(ctx, `/api/v1/agent/portfolio/summary?${query.toString()}`);
|
|
864
|
+
printEnvelope({
|
|
865
|
+
success: true,
|
|
866
|
+
code: 'ANALYTICS_PORTFOLIO_OK',
|
|
867
|
+
message: 'Agent portfolio summary loaded',
|
|
868
|
+
data: response,
|
|
869
|
+
meta: metaPortfolioListingFilters(ctx, flags, capabilities, agentKey),
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
async function commandAnalyticsLeaderboard(ctx, flags, capabilities) {
|
|
874
|
+
const query = new URLSearchParams();
|
|
875
|
+
const window = flags.window || '7d';
|
|
876
|
+
const metric = flags.metric || 'roiPct';
|
|
877
|
+
applySharedPortfolioListingFiltersToQuery(query, flags);
|
|
878
|
+
query.set('window', String(window));
|
|
879
|
+
query.set('metric', String(metric));
|
|
880
|
+
if (flags.limit) query.set('limit', String(flags.limit));
|
|
881
|
+
const response = await apiGet(ctx, `/api/v1/agent/portfolio/leaderboard?${query.toString()}`);
|
|
882
|
+
printEnvelope({
|
|
883
|
+
success: true,
|
|
884
|
+
code: 'ANALYTICS_LEADERBOARD_OK',
|
|
885
|
+
message: 'Agent portfolio leaderboard loaded',
|
|
886
|
+
data: response,
|
|
822
887
|
meta: {
|
|
823
888
|
apiBase: ctx.apiBase,
|
|
824
|
-
|
|
825
|
-
|
|
889
|
+
networkId: flags.networkId || flags.network || null,
|
|
890
|
+
chainType: flags.chainType || null,
|
|
891
|
+
category: flags.category || null,
|
|
892
|
+
window,
|
|
893
|
+
metric,
|
|
894
|
+
capabilitiesVersion: capabilities?.contractVersion || null,
|
|
826
895
|
},
|
|
827
896
|
});
|
|
828
897
|
}
|
|
@@ -3228,6 +3297,172 @@ function formatActionList(items) {
|
|
|
3228
3297
|
.join(', ');
|
|
3229
3298
|
}
|
|
3230
3299
|
|
|
3300
|
+
function normalizeProviderId(value) {
|
|
3301
|
+
return String(value || '').trim().toLowerCase();
|
|
3302
|
+
}
|
|
3303
|
+
|
|
3304
|
+
function rowActionKey(action) {
|
|
3305
|
+
return getActionKey(action)
|
|
3306
|
+
.replace(/-/g, '_')
|
|
3307
|
+
.toLowerCase();
|
|
3308
|
+
}
|
|
3309
|
+
|
|
3310
|
+
function canonicalActionKey(action) {
|
|
3311
|
+
return getActionKey(action)
|
|
3312
|
+
.replace(/_/g, '-')
|
|
3313
|
+
.toLowerCase();
|
|
3314
|
+
}
|
|
3315
|
+
|
|
3316
|
+
function inferActionProvider(action) {
|
|
3317
|
+
// API catalog metadata (`providerId`, `domain`, `category`) is the source of truth.
|
|
3318
|
+
// This fallback only keeps older catalog rows / older API deployments discoverable.
|
|
3319
|
+
const key = canonicalActionKey(action);
|
|
3320
|
+
const knownMap = {
|
|
3321
|
+
swap: 'trading',
|
|
3322
|
+
'execute-optimal-swap': 'trading',
|
|
3323
|
+
'get-best-trading-quote': 'trading',
|
|
3324
|
+
'dogeos-barkswap-get-quote': 'dogeos-barkswap',
|
|
3325
|
+
'dogeos-barkswap-execute-swap': 'dogeos-barkswap',
|
|
3326
|
+
'dogeos-get-ecosystem-overview': 'dogeos-ecosystem',
|
|
3327
|
+
'dogeos-get-wallet-actionability': 'dogeos-ecosystem',
|
|
3328
|
+
'dogeos-prepare-trade': 'dogeos-ecosystem',
|
|
3329
|
+
'dogeos-prepare-token-launch': 'dogeos-ecosystem',
|
|
3330
|
+
'dogeos-get-chain-insights': 'dogeos-ecosystem',
|
|
3331
|
+
'dogeos-get-trending-tokens': 'dogeos-ecosystem',
|
|
3332
|
+
'dogeos-get-new-tokens': 'dogeos-ecosystem',
|
|
3333
|
+
'dogeos-get-early-bird-tokens': 'dogeos-ecosystem',
|
|
3334
|
+
'dogeos-get-only-moon-tokens': 'dogeos-ecosystem',
|
|
3335
|
+
'dogeos-get-big-wins-tokens': 'dogeos-ecosystem',
|
|
3336
|
+
'dogeos-get-related-tokens': 'dogeos-ecosystem',
|
|
3337
|
+
'dogeos-laika-read-contract': 'dogeos-laika',
|
|
3338
|
+
'dogeos-laika-execute-raw': 'dogeos-laika',
|
|
3339
|
+
'dogeos-laika-launch-token': 'dogeos-laika',
|
|
3340
|
+
'dogeos-laika-buy-token': 'dogeos-laika',
|
|
3341
|
+
'dogeos-laika-claim': 'dogeos-laika',
|
|
3342
|
+
'dogeos-laika-token-state': 'dogeos-laika',
|
|
3343
|
+
'get-governance-v2-overview': 'governance-v2',
|
|
3344
|
+
'get-governance-v2-timeseries': 'governance-v2',
|
|
3345
|
+
'get-governance-v2-breakdowns': 'governance-v2',
|
|
3346
|
+
'get-hyperliquid-perps-meta': 'hyperliquid',
|
|
3347
|
+
'get-hyperliquid-all-mids': 'hyperliquid',
|
|
3348
|
+
'get-hyperliquid-l2-book': 'hyperliquid',
|
|
3349
|
+
'get-hyperliquid-candles': 'hyperliquid',
|
|
3350
|
+
'get-hyperliquid-user-state': 'hyperliquid',
|
|
3351
|
+
'get-hyperliquid-open-orders': 'hyperliquid',
|
|
3352
|
+
'get-hyperliquid-setup-status': 'hyperliquid',
|
|
3353
|
+
'get-hyperliquid-onboarding-plan': 'hyperliquid',
|
|
3354
|
+
'prepare-hyperliquid-onboarding': 'hyperliquid',
|
|
3355
|
+
'claim-hyperliquid-testnet-faucet': 'hyperliquid',
|
|
3356
|
+
'get-hyperliquid-builder-fee-status': 'hyperliquid',
|
|
3357
|
+
'approve-hyperliquid-agent': 'hyperliquid',
|
|
3358
|
+
'approve-hyperliquid-builder-fee': 'hyperliquid',
|
|
3359
|
+
'register-hyperliquid-referrer': 'hyperliquid',
|
|
3360
|
+
'set-hyperliquid-referrer': 'hyperliquid',
|
|
3361
|
+
'get-hyperliquid-referral-status': 'hyperliquid',
|
|
3362
|
+
'deposit-hyperliquid-staking': 'hyperliquid',
|
|
3363
|
+
'deposit-hyperliquid-bridge': 'hyperliquid',
|
|
3364
|
+
'place-hyperliquid-perps-order': 'hyperliquid',
|
|
3365
|
+
'get-perps-markets': 'hyperliquid',
|
|
3366
|
+
'get-perps-account': 'hyperliquid',
|
|
3367
|
+
'get-perps-position': 'hyperliquid',
|
|
3368
|
+
'place-perps-order': 'hyperliquid',
|
|
3369
|
+
'cancel-perps-order': 'hyperliquid',
|
|
3370
|
+
'get-earn-opportunities': 'earn',
|
|
3371
|
+
'get-earn-provider': 'earn',
|
|
3372
|
+
'get-earn-position': 'earn',
|
|
3373
|
+
'deposit-earn-position': 'earn',
|
|
3374
|
+
'withdraw-earn-position': 'earn',
|
|
3375
|
+
'get-morpho-vaults': 'morpho',
|
|
3376
|
+
'deposit-morpho-vault': 'morpho',
|
|
3377
|
+
'withdraw-morpho-vault': 'morpho',
|
|
3378
|
+
'get-curve-pools': 'curve',
|
|
3379
|
+
'get-curve-pool-details': 'curve',
|
|
3380
|
+
'deposit-curve-pool': 'curve',
|
|
3381
|
+
'withdraw-curve-pool': 'curve',
|
|
3382
|
+
'get-prediction-markets': 'polymarket',
|
|
3383
|
+
'get-prediction-market': 'polymarket',
|
|
3384
|
+
'get-prediction-order-book': 'polymarket',
|
|
3385
|
+
'get-prediction-position': 'polymarket',
|
|
3386
|
+
'place-prediction-order': 'polymarket',
|
|
3387
|
+
'cancel-prediction-order': 'polymarket',
|
|
3388
|
+
'get-polymarket-markets': 'polymarket',
|
|
3389
|
+
'get-polymarket-market': 'polymarket',
|
|
3390
|
+
'get-polymarket-setup-status': 'polymarket',
|
|
3391
|
+
'get-polymarket-order': 'polymarket',
|
|
3392
|
+
'place-polymarket-order': 'polymarket',
|
|
3393
|
+
};
|
|
3394
|
+
if (knownMap[key]) return knownMap[key];
|
|
3395
|
+
if (key.includes('hyperliquid')) return 'hyperliquid';
|
|
3396
|
+
if (key.includes('polymarket') || key.includes('prediction')) return 'polymarket';
|
|
3397
|
+
if (key.includes('morpho')) return 'morpho';
|
|
3398
|
+
if (key.includes('curve')) return 'curve';
|
|
3399
|
+
if (key.includes('earn')) return 'earn';
|
|
3400
|
+
if (key.includes('bridge')) return 'bridge';
|
|
3401
|
+
if (key.includes('dogeos-barkswap')) return 'dogeos-barkswap';
|
|
3402
|
+
if (key.includes('dogeos-laika')) return 'dogeos-laika';
|
|
3403
|
+
if (key.includes('dogeos')) return 'dogeos-ecosystem';
|
|
3404
|
+
return '';
|
|
3405
|
+
}
|
|
3406
|
+
|
|
3407
|
+
function getActionProviderWithInference(action) {
|
|
3408
|
+
return getActionProvider(action) || inferActionProvider(action);
|
|
3409
|
+
}
|
|
3410
|
+
|
|
3411
|
+
function isEarnCatalogAction(action) {
|
|
3412
|
+
const actionKey = rowActionKey(action);
|
|
3413
|
+
return (
|
|
3414
|
+
actionKey.includes('_earn_') ||
|
|
3415
|
+
normalizeProviderId(action?.domain) === 'earn' ||
|
|
3416
|
+
normalizeProviderId(action?.category) === 'earn'
|
|
3417
|
+
);
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3420
|
+
function isSpotTradingCatalogAction(action) {
|
|
3421
|
+
const actionKey = rowActionKey(action);
|
|
3422
|
+
return actionKey === 'swap' || actionKey === 'execute_optimal_swap' || actionKey === 'get_best_trading_quote';
|
|
3423
|
+
}
|
|
3424
|
+
|
|
3425
|
+
function isProviderActionKey(action, provider) {
|
|
3426
|
+
const actionKey = rowActionKey(action);
|
|
3427
|
+
const normalizedProvider = normalizeProviderId(provider).replace(/-/g, '_');
|
|
3428
|
+
if (!actionKey || !normalizedProvider) return false;
|
|
3429
|
+
return (
|
|
3430
|
+
actionKey === normalizedProvider ||
|
|
3431
|
+
actionKey.startsWith(`${normalizedProvider}_`) ||
|
|
3432
|
+
actionKey.includes(`_${normalizedProvider}_`) ||
|
|
3433
|
+
actionKey.endsWith(`_${normalizedProvider}`)
|
|
3434
|
+
);
|
|
3435
|
+
}
|
|
3436
|
+
|
|
3437
|
+
function actionMatchesProvider(action, requestedProvider, allActions) {
|
|
3438
|
+
const provider = getActionProviderWithInference(action);
|
|
3439
|
+
const actionKey = rowActionKey(action);
|
|
3440
|
+
if (provider === requestedProvider) return true;
|
|
3441
|
+
if (requestedProvider === 'trading') return isSpotTradingCatalogAction(action);
|
|
3442
|
+
// Here resolved metadata already disagrees with the filter; fall back to action-key shape only.
|
|
3443
|
+
if (requestedProvider === 'hyperliquid') return isProviderActionKey(action, 'hyperliquid');
|
|
3444
|
+
if (requestedProvider === 'polymarket') return isProviderActionKey(action, 'polymarket');
|
|
3445
|
+
if (requestedProvider === 'bridge') return isProviderActionKey(action, 'bridge');
|
|
3446
|
+
if (requestedProvider.startsWith('dogeos')) return isProviderActionKey(action, requestedProvider);
|
|
3447
|
+
if (requestedProvider === 'earn') {
|
|
3448
|
+
return provider === 'earn' || provider === 'morpho' || provider === 'curve' || isEarnCatalogAction(action);
|
|
3449
|
+
}
|
|
3450
|
+
if (requestedProvider === 'morpho' || requestedProvider === 'curve') {
|
|
3451
|
+
const hasProtocolSpecificEarnRows = allActions.some((candidate) => getActionProviderWithInference(candidate) === requestedProvider);
|
|
3452
|
+
return isProviderActionKey(action, requestedProvider) || (!hasProtocolSpecificEarnRows && isEarnCatalogAction(action));
|
|
3453
|
+
}
|
|
3454
|
+
if (requestedProvider === 'prediction') {
|
|
3455
|
+
return (
|
|
3456
|
+
provider === 'polymarket' ||
|
|
3457
|
+
provider === 'prediction' ||
|
|
3458
|
+
actionKey.includes('_prediction_') ||
|
|
3459
|
+
normalizeProviderId(action?.domain) === 'prediction' ||
|
|
3460
|
+
normalizeProviderId(action?.category) === 'prediction'
|
|
3461
|
+
);
|
|
3462
|
+
}
|
|
3463
|
+
return isProviderActionKey(action, requestedProvider);
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3231
3466
|
function applyActionFilters(actions, flags) {
|
|
3232
3467
|
let filtered = actions;
|
|
3233
3468
|
if (flags.catalog) {
|
|
@@ -3235,21 +3470,14 @@ function applyActionFilters(actions, flags) {
|
|
|
3235
3470
|
filtered = filtered.filter((a) => String(a.catalog || a.catalogId || 'default').trim().toLowerCase() === expectedCatalog);
|
|
3236
3471
|
}
|
|
3237
3472
|
if (flags.provider) {
|
|
3238
|
-
const expectedProvider =
|
|
3239
|
-
filtered = filtered.filter((a) =>
|
|
3240
|
-
const provider = getActionProvider(a);
|
|
3241
|
-
const actionKey = getActionKey(a).replace(/-/g, '_').toLowerCase();
|
|
3242
|
-
if (provider === expectedProvider) return true;
|
|
3243
|
-
if (expectedProvider === 'earn') return provider === 'morpho' || provider === 'curve' || actionKey.includes('_earn_');
|
|
3244
|
-
if (expectedProvider === 'prediction') return provider === 'polymarket' || actionKey.includes('_prediction_');
|
|
3245
|
-
return false;
|
|
3246
|
-
});
|
|
3473
|
+
const expectedProvider = normalizeProviderId(flags.provider);
|
|
3474
|
+
filtered = filtered.filter((a) => actionMatchesProvider(a, expectedProvider, filtered));
|
|
3247
3475
|
}
|
|
3248
3476
|
return filtered;
|
|
3249
3477
|
}
|
|
3250
3478
|
|
|
3251
3479
|
function getActionProvider(action) {
|
|
3252
|
-
return
|
|
3480
|
+
return normalizeProviderId(action?.provider || action?.providerId || action?.provider_id || action?.catalog || '');
|
|
3253
3481
|
}
|
|
3254
3482
|
|
|
3255
3483
|
async function resolveActionSelection(ctx, flags) {
|
|
@@ -3850,7 +4078,9 @@ Core commands:
|
|
|
3850
4078
|
thirdfy-agent whoami [--json]
|
|
3851
4079
|
thirdfy-agent catalogs list [--json]
|
|
3852
4080
|
thirdfy-agent actions [--catalog <id>] [--provider <id>] [--agent-api-key <key>] [--chain-id <id>] [--run-mode <mode>] [--json]
|
|
3853
|
-
thirdfy-agent data summary --agent-key <key> [--chain-id <id>] [--limit <n>] [--json]
|
|
4081
|
+
thirdfy-agent data summary --agent-key <key> [--chain-id <id>] [--network <id>] [--category trading|yield|prediction] [--limit <n>] [--json]
|
|
4082
|
+
thirdfy-agent analytics portfolio --agent-key <key> [--network base-mainnet] [--category trading|yield|prediction] [--json]
|
|
4083
|
+
thirdfy-agent analytics leaderboard [--category trading|yield|prediction] [--network base-mainnet] [--window 24h|7d|30d|all] [--metric roiPct|pnlUsd|aprPct|currentValueUsd] [--json]
|
|
3854
4084
|
thirdfy-agent track actions --agent-key <key> [--limit <n>] [--json]
|
|
3855
4085
|
thirdfy-agent track events --agent-key <key> [--limit <n>] [--json]
|
|
3856
4086
|
thirdfy-agent track action --agent-api-key <key> --action <name> [--category <name>] [--source agent|external_mcp|operator|thirdfy|custom] [--provider <id>] [--protocol <id>] [--namespace <name>] [--action-type supported|custom] [--status observed|planned|skipped|submitted|confirmed|failed|blocked] [--chain-id <id>] [--params <json>] [--json]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thirdfy/agent-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
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",
|