@thirdfy/agent-cli 0.2.70 → 0.2.71

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,6 +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.2.71] - 2026-09-16
8
+
9
+ ### Fixed
10
+
11
+ - `get_avantis_setup_status` / `get_avantis_onboarding_plan` use the 180s compose timeout. Empty queued `/execute-intent` fallbacks fail as `MANAGED_READ_EMPTY_EXECUTE_INTENT` instead of a successful empty setup payload. Pin: `test/actionTimeouts.test.cjs`, `test/agent-wallet-readonly-fallback.test.cjs`. Matches `thirdfy-mcp` **0.0.121**.
12
+
7
13
  ## [0.2.70] - 2026-09-16
8
14
 
9
15
  ### Fixed
package/README.md CHANGED
@@ -40,10 +40,10 @@ Run without global install:
40
40
  npx @thirdfy/agent-cli --help
41
41
  ```
42
42
 
43
- ## What's new in v0.2.70
43
+ ## What's new in v0.2.71
44
44
 
45
- - `--action get_aave_markets` resolves to the first-class catalog key before colliding earn aliases.
46
- - Hosted runtime write keys stay scoped by runtime UUID so Thirdfy action events can join.
45
+ - Avantis setup-status and onboarding-plan reads wait for the compose timeout instead of falling back early.
46
+ - An empty queued execute-intent fallback fails instead of looking like a successful empty setup payload.
47
47
  - See [CHANGELOG.md](./CHANGELOG.md) and GitHub Releases for older versions.
48
48
 
49
49
  ## Quick start
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thirdfy/agent-cli",
3
- "version": "0.2.70",
3
+ "version": "0.2.71",
4
4
  "description": "Thirdfy Agent CLI for onboarding, governance preflight, execute-intent, and status polling.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,6 +2,8 @@ import { DEFAULT_TIMEOUT_MS } from './constants.mjs';
2
2
 
3
3
  const LONG_RUNNING_ACTIONS = new Set([
4
4
  'complete_avantis_onboarding',
5
+ 'get_avantis_setup_status',
6
+ 'get_avantis_onboarding_plan',
5
7
  'complete_lighter_onboarding',
6
8
  'setup_lighter_api_key',
7
9
  'register_lighter_api_key',
@@ -23,7 +25,7 @@ function normalizeActionId(action) {
23
25
  .toLowerCase();
24
26
  }
25
27
 
26
- /** Longer HTTP timeout for Lighter onboarding and Morpho/Aave earn writes (approve + vault call). */
28
+ /** Longer HTTP timeout for Avantis/Lighter onboarding, Avantis setup-status compose, and Morpho/Aave earn writes. */
27
29
  export function resolveActionTimeoutMs(action, baseTimeoutMs = DEFAULT_TIMEOUT_MS) {
28
30
  const base = Number.isFinite(baseTimeoutMs) && baseTimeoutMs > 0 ? baseTimeoutMs : DEFAULT_TIMEOUT_MS;
29
31
  if (!LONG_RUNNING_ACTIONS.has(normalizeActionId(action))) return base;
@@ -12,6 +12,20 @@ export function managedReadExecuteErrorText(data) {
12
12
  return String(data?.error || data?.message || data?.code || data?.blockedReason || '').toLowerCase();
13
13
  }
14
14
 
15
+ export function isEmptyQueuedExecuteIntent(data) {
16
+ const rec = data && typeof data === 'object' && !Array.isArray(data) ? data : null;
17
+ if (!rec) return false;
18
+ // Read payloads live in `data`. Do not mix those fields with outer batch defaults —
19
+ // `normalizeIntentResponse` materializes status=queued, executed=0, results=[].
20
+ const nested = rec.data && typeof rec.data === 'object' && !Array.isArray(rec.data) ? rec.data : rec;
21
+ const status = String(nested.status ?? '').toLowerCase();
22
+ const executed = Number(nested.executed);
23
+ const results = nested.results;
24
+ const emptyResults = Array.isArray(results) && results.length === 0;
25
+ const queued = status === 'queued' || (Number.isFinite(executed) && executed === 0);
26
+ return queued && emptyResults;
27
+ }
28
+
15
29
  export function shouldFallbackManagedReadToExecuteIntent({ isReadOnly, errorText } = {}) {
16
30
  if (!isReadOnly) return false;
17
31
  const err = String(errorText || '').toLowerCase();
@@ -12,7 +12,7 @@ import {
12
12
  import { apiGet, apiPost } from '../../core/http.mjs';
13
13
  import { withActionTimeout } from '../../core/actionTimeouts.mjs';
14
14
  import { isReadOnlyResolvedAction } from '../../core/readOnlyActions.mjs';
15
- import { shouldFallbackManagedReadToExecuteIntent } from './managedReadExecuteRail.mjs';
15
+ import { isEmptyQueuedExecuteIntent, shouldFallbackManagedReadToExecuteIntent } from './managedReadExecuteRail.mjs';
16
16
  import { createRequire } from 'module';
17
17
 
18
18
  const require = createRequire(import.meta.url);
@@ -506,6 +506,11 @@ async function executeManagedWalletRun(ctx, flags, resolved, options) {
506
506
  const response = await apiPost(actionCtx, '/api/v1/agent/execute', payload);
507
507
  if (shouldFallbackAgentWalletToExecuteIntent(resolved, response)) {
508
508
  const intentResult = await runReadOnlyActionViaIntentRail(ctx, flags, resolved, options, preflight);
509
+ if (isEmptyQueuedExecuteIntent(intentResult.raw || intentResult)) {
510
+ intentResult.success = false;
511
+ intentResult.status = 'failed';
512
+ intentResult.error = intentResult.error || 'MANAGED_READ_EMPTY_EXECUTE_INTENT';
513
+ }
509
514
  intentResult.executionWalletAddress =
510
515
  preflight?.executionWalletAddress ||
511
516
  response?.executionWalletAddress ||