@thirdfy/agent-cli 0.1.27 → 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 CHANGED
@@ -4,8 +4,12 @@ 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
+
7
9
  ### Added
8
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`.
9
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.
10
14
 
11
15
  ### Fixed
@@ -15,6 +19,8 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
15
19
 
16
20
  ### Changed
17
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.
18
24
  - **CI:** Release workflow no longer requests `id-token: write` (npm publish uses `secrets.NPM_TOKEN` only).
19
25
 
20
26
  ## [0.1.27] - 2026-05-05
package/README.md CHANGED
@@ -40,7 +40,7 @@ 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 provider discovery parity, metadata-first `actions --provider` filtering, earn deposit guards, and README refresh through **v0.1.27**.
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
44
 
45
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.
46
46
 
@@ -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
- async function commandDataSummary(ctx, flags, capabilities) {
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
- if (flags.chainId) query.set('chainId', String(flags.chainId));
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
- agentKey,
825
- chainId: flags.chainId ? Number(flags.chainId) : null,
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
  }
@@ -4009,7 +4078,9 @@ Core commands:
4009
4078
  thirdfy-agent whoami [--json]
4010
4079
  thirdfy-agent catalogs list [--json]
4011
4080
  thirdfy-agent actions [--catalog <id>] [--provider <id>] [--agent-api-key <key>] [--chain-id <id>] [--run-mode <mode>] [--json]
4012
- 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]
4013
4084
  thirdfy-agent track actions --agent-key <key> [--limit <n>] [--json]
4014
4085
  thirdfy-agent track events --agent-key <key> [--limit <n>] [--json]
4015
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.27",
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": {