@thirdfy/agent-cli 0.4.1 → 0.4.2

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +4 -5
  3. package/package.json +3 -3
  4. package/src/cli/options/index.mjs +11 -11
  5. package/src/cli/program.mjs +1 -1
  6. package/src/commands/{agent.mjs → account/agent.mjs} +5 -5
  7. package/src/commands/{credits.mjs → account/credits.mjs} +13 -15
  8. package/src/commands/{wallet.mjs → account/wallet.mjs} +29 -33
  9. package/src/commands/{walletControl.mjs → account/walletControl.mjs} +3 -3
  10. package/src/commands/discovery.mjs +1 -1
  11. package/src/commands/execute.mjs +2 -2
  12. package/src/commands/index.mjs +9 -9
  13. package/src/commands/{bootstrap.mjs → onboarding/bootstrap.mjs} +8 -8
  14. package/src/commands/{consoleMandate.mjs → onboarding/consoleMandate.mjs} +2 -2
  15. package/src/commands/{credentials.mjs → onboarding/credentials.mjs} +6 -6
  16. package/src/commands/{delegation.mjs → onboarding/delegation.mjs} +5 -5
  17. package/src/commands/{avantis.mjs → venues/avantis.mjs} +1 -1
  18. package/src/commands/{condor.mjs → venues/condor.mjs} +4 -4
  19. package/src/commands/{hummingbot.mjs → venues/hummingbot.mjs} +4 -4
  20. package/src/commands/{hyperliquid.mjs → venues/hyperliquid.mjs} +1 -1
  21. package/src/commands/{lighter.mjs → venues/lighter.mjs} +1 -1
  22. package/src/commands/{polymarket.mjs → venues/polymarket.mjs} +4 -4
  23. package/src/commands/{venue.mjs → venues/venue.mjs} +3 -3
  24. package/src/core/earnclawAttribution.mjs +1 -1
  25. package/src/core/{actionTimeouts.mjs → execution/actionTimeouts.mjs} +2 -2
  26. package/src/core/{walletExecuteChainId.mjs → execution/walletExecuteChainId.mjs} +1 -1
  27. package/src/core/http.mjs +1 -1
  28. package/src/runtime/execution/hostedRuntimeWriteGate.mjs +1 -1
  29. package/src/runtime/execution/payloads.mjs +4 -4
  30. package/src/runtime/execution/runners/agentWalletLane.mjs +109 -0
  31. package/src/runtime/execution/runners/createExecutionRunners.mjs +315 -0
  32. package/src/runtime/execution/runners/fallbackHints.mjs +54 -0
  33. package/src/runtime/execution/runners/hybridLane.mjs +88 -0
  34. package/src/runtime/execution/runners/managedPreflight.mjs +253 -0
  35. package/src/runtime/execution/runners/managedResponse.mjs +119 -0
  36. package/src/runtime/execution/runners/selfLane.mjs +232 -0
  37. package/src/runtime/execution/runners/thirdfyLane.mjs +97 -0
  38. package/src/runtime/execution/svmLane.mjs +1 -1
  39. package/src/runtime/handlers.mjs +15 -16
  40. package/src/runtime/main.mjs +1 -1
  41. package/src/runtime/risk/notional.mjs +1 -1
  42. package/src/runtime/validation/actionParamsGate.mjs +1 -1
  43. package/src/runtime/execution/runners.mjs +0 -1134
  44. /package/src/cli/options/{agent.mjs → account/agent.mjs} +0 -0
  45. /package/src/cli/options/{credits.mjs → account/credits.mjs} +0 -0
  46. /package/src/cli/options/{wallet.mjs → account/wallet.mjs} +0 -0
  47. /package/src/cli/options/{walletControl.mjs → account/walletControl.mjs} +0 -0
  48. /package/src/cli/options/{bootstrap.mjs → onboarding/bootstrap.mjs} +0 -0
  49. /package/src/cli/options/{credentials.mjs → onboarding/credentials.mjs} +0 -0
  50. /package/src/cli/options/{delegation.mjs → onboarding/delegation.mjs} +0 -0
  51. /package/src/cli/options/{condor.mjs → venues/condor.mjs} +0 -0
  52. /package/src/cli/options/{hummingbot.mjs → venues/hummingbot.mjs} +0 -0
  53. /package/src/cli/options/{polymarket.mjs → venues/polymarket.mjs} +0 -0
  54. /package/src/cli/options/{venue.mjs → venues/venue.mjs} +0 -0
  55. /package/src/core/{executionContext.mjs → execution/executionContext.mjs} +0 -0
  56. /package/src/core/{fundingTokenIn.mjs → execution/fundingTokenIn.mjs} +0 -0
  57. /package/src/core/{hostedRuntimeIdempotency.mjs → execution/hostedRuntimeIdempotency.mjs} +0 -0
  58. /package/src/core/{readOnlyActions.mjs → execution/readOnlyActions.mjs} +0 -0
  59. /package/src/core/{signedTx.mjs → execution/signedTx.mjs} +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,26 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## [0.4.2] - 2026-10-14
8
+
9
+ A cleanup release: two small `wallet profile` / `pricing quote` fixes from the 0.4.1 review, and source files moved into domain folders. Commands answer as in 0.4.1, apart from the two fixes.
10
+
11
+ ### Fixed
12
+
13
+ - **`wallet profile` and `readiness` report the agent key in lowercase** whether it came from `--agent-key` or from env/config. Before, a checksummed config key was echoed as stored, so one agent could appear with two spellings.
14
+ - **`pricing quote` on an API without the agent quote route** names the agent only from `--agent-key`. The branch that took the configured agent could not be reached (a stored owner token already puts the quote on the owner ledger) and is removed.
15
+
16
+ ### Changed
17
+
18
+ - **Source files moved into domain subfolders (no behavior change).** The `thirdfy-agent` command is unchanged. Code that deep-imports package files must use the new paths:
19
+ - `src/runtime/execution/runners.mjs` → `src/runtime/execution/runners/` (one file per lane; `createExecutionRunners` is in `createExecutionRunners.mjs`).
20
+ - `src/core/{actionTimeouts,executionContext,fundingTokenIn,hostedRuntimeIdempotency,readOnlyActions,signedTx,walletExecuteChainId}.mjs` → `src/core/execution/`.
21
+ - `src/commands/{avantis,condor,hummingbot,hyperliquid,lighter,polymarket,venue}.mjs` → `src/commands/venues/`; `{bootstrap,consoleMandate,credentials,delegation}.mjs` → `src/commands/onboarding/`; `{agent,credits,wallet,walletControl}.mjs` → `src/commands/account/`.
22
+ - `src/cli/options/` uses the same `venues/`, `onboarding/` and `account/` subfolders.
23
+ - `src/core/index.mjs` and `src/commands/index.mjs` export the same names as before.
24
+ - `wallet profile` uses the same owner/agent precedence code as the credits commands (`resolveCreditsLedger`) instead of its own copy. Same behavior.
25
+ - `validate:provider-parity` names the files it looked in when it finds no MCP provider-hints file.
26
+
7
27
  ## [0.4.1] - 2026-10-14
8
28
 
9
29
  The last MCP tool with no CLI command (`wallet profile`), who pays for an action (`pricing quote`), owner session tokens for credits, and a parity check that follows thirdfy-mcp's new file layout.
package/README.md CHANGED
@@ -40,12 +40,11 @@ Run without global install:
40
40
  npx @thirdfy/agent-cli --help
41
41
  ```
42
42
 
43
- ## What's new in v0.4.1
43
+ ## What's new in v0.4.2
44
44
 
45
- - **`wallet profile`:** the live wallet profile from the API. With owner auth, the owner's onboarding profile; with an agent key, the agent's execution wallet with `ready`, wallet control and the next step. Every thirdfy-mcp tool that applies to a CLI now has a command.
46
- - **`pricing quote` says who would pay:** the agent's credits, a free request, the owner's credits, or nobody (`wouldBePaidBy`), in credits only.
47
- - **Owner session tokens** work for `credits balance` and `pricing quote`, and both pick the agent or owner ledger the same way as `wallet profile`.
48
- - **Safer agent identity:** with an explicit `--agent-api-key`, `readiness`, `wallet profile` and `pricing quote` name the agent from `--agent-key`, never a configured agent that may belong to another key.
45
+ - **One spelling per agent:** `wallet profile` and `readiness` report the agent key in lowercase, whether it came from `--agent-key` or from your config.
46
+ - **`pricing quote` on an older API** (no agent quote route) names the agent only from `--agent-key`.
47
+ - **Reorganized source** (no behavior change): source files moved into domain folders. If your code imports files from inside the package, see [CHANGELOG.md](./CHANGELOG.md) for the new paths; the `thirdfy-agent` command is unchanged.
49
48
  - Older versions: see [CHANGELOG.md](./CHANGELOG.md).
50
49
 
51
50
  ## Quick start
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thirdfy/agent-cli",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Thirdfy Agent CLI for onboarding, governance preflight, execute-intent, and status polling.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,8 +22,8 @@
22
22
  "LICENSE"
23
23
  ],
24
24
  "scripts": {
25
- "test": "node --test test/*.test.cjs",
26
- "lint": "node --check ./bin/thirdfy-agent.mjs && node --check ./src/core/*.mjs && node --check ./src/commands/*.mjs && node --check ./src/commands/signals/*.mjs && node --check ./src/cli/*.mjs && node --check ./src/cli/options/*.mjs && node --check ./src/runtime/*.mjs && node --check ./src/runtime/execution/*.mjs && node --check ./src/runtime/actions/*.mjs && node --check ./src/runtime/validation/*.mjs && node --check ./src/runtime/certification/*.mjs && node --check ./src/runtime/providerHints/*.mjs && node --check ./src/runtime/risk/*.mjs",
25
+ "test": "node --test test/*/*.test.cjs test/*/*/*.test.cjs",
26
+ "lint": "node --check ./bin/thirdfy-agent.mjs && node --check ./src/core/*.mjs && node --check ./src/core/execution/*.mjs && node --check ./src/commands/*.mjs && node --check ./src/commands/venues/*.mjs && node --check ./src/commands/onboarding/*.mjs && node --check ./src/commands/account/*.mjs && node --check ./src/commands/signals/*.mjs && node --check ./src/cli/*.mjs && node --check ./src/cli/options/*.mjs && node --check ./src/cli/options/venues/*.mjs && node --check ./src/cli/options/onboarding/*.mjs && node --check ./src/cli/options/account/*.mjs && node --check ./src/runtime/*.mjs && node --check ./src/runtime/execution/*.mjs && node --check ./src/runtime/execution/runners/*.mjs && node --check ./src/runtime/actions/*.mjs && node --check ./src/runtime/validation/*.mjs && node --check ./src/runtime/certification/*.mjs && node --check ./src/runtime/providerHints/*.mjs && node --check ./src/runtime/risk/*.mjs",
27
27
  "validate:cli-manifest-handlers": "node ./scripts/validate-cli-manifest-handlers.mjs",
28
28
  "validate:runtime-boundaries": "node ./scripts/validate-runtime-boundaries.mjs",
29
29
  "validate:npm-pack": "node ./scripts/validate-npm-pack.mjs",
@@ -1,24 +1,24 @@
1
1
  import { attachGlobalOptions } from './global.mjs';
2
2
  import { attachAuthOptions } from './auth.mjs';
3
3
  import { attachExecutionOptions } from './execution.mjs';
4
- import { attachDelegationOptions } from './delegation.mjs';
4
+ import { attachDelegationOptions } from './onboarding/delegation.mjs';
5
5
  import { attachTrackingOptions } from './tracking.mjs';
6
- import { attachWalletOptions } from './wallet.mjs';
7
- import { attachBootstrapOptions, attachOnboardingHelpOptions } from './bootstrap.mjs';
8
- import { attachCredentialsOptions } from './credentials.mjs';
6
+ import { attachWalletOptions } from './account/wallet.mjs';
7
+ import { attachBootstrapOptions, attachOnboardingHelpOptions } from './onboarding/bootstrap.mjs';
8
+ import { attachCredentialsOptions } from './onboarding/credentials.mjs';
9
9
  import { attachAnalyticsOptions } from './analytics.mjs';
10
- import { attachPolymarketOptions } from './polymarket.mjs';
11
- import { attachHummingbotOptions } from './hummingbot.mjs';
12
- import { attachCondorOptions } from './condor.mjs';
13
- import { attachAgentRegisterOptions } from './agent.mjs';
10
+ import { attachPolymarketOptions } from './venues/polymarket.mjs';
11
+ import { attachHummingbotOptions } from './venues/hummingbot.mjs';
12
+ import { attachCondorOptions } from './venues/condor.mjs';
13
+ import { attachAgentRegisterOptions } from './account/agent.mjs';
14
14
  import { attachChainListOptions, attachChainOptions } from './chains.mjs';
15
- import { attachCreditsBuyOptions, attachCreditsOptions } from './credits.mjs';
15
+ import { attachCreditsBuyOptions, attachCreditsOptions } from './account/credits.mjs';
16
16
  import { attachChatOptions } from './chat.mjs';
17
- import { attachVenueOptions } from './venue.mjs';
17
+ import { attachVenueOptions } from './venues/venue.mjs';
18
18
  import { attachBrainOptions } from './brain.mjs';
19
19
  import { attachCertificationOptions } from './certification.mjs';
20
20
  import { attachActionListOptions, attachDataCategoryOptions, attachSignalsOptions } from './data.mjs';
21
- import { attachWalletControlOptions } from './walletControl.mjs';
21
+ import { attachWalletControlOptions } from './account/walletControl.mjs';
22
22
 
23
23
  const BUNDLES = {
24
24
  auth: attachAuthOptions,
@@ -3,4 +3,4 @@ import { buildCliProgram } from './register.mjs';
3
3
  export { buildCliProgram };
4
4
  export { collectRootFlags, collectLegacyFlags } from './flags.mjs';
5
5
  export { configureCommanderErrors, handleRootOnlyFlows, collectVersionFlagsFromArgv } from './errors.mjs';
6
- export { normalizeLegacyShortFlags } from './options/bootstrap.mjs';
6
+ export { normalizeLegacyShortFlags } from './options/onboarding/bootstrap.mjs';
@@ -1,11 +1,11 @@
1
1
  import { createRequire } from 'module';
2
- import { requireFlag, parseJsonFlag } from '../core/args.mjs';
3
- import { apiPost, safeJsonParse } from '../core/http.mjs';
4
- import { createCliError } from '../core/envelope.mjs';
5
- import { DEFAULT_TIMEOUT_MS } from '../core/constants.mjs';
2
+ import { requireFlag, parseJsonFlag } from '../../core/args.mjs';
3
+ import { apiPost, safeJsonParse } from '../../core/http.mjs';
4
+ import { createCliError } from '../../core/envelope.mjs';
5
+ import { DEFAULT_TIMEOUT_MS } from '../../core/constants.mjs';
6
6
 
7
7
  const require = createRequire(import.meta.url);
8
- const { version: CLI_VERSION } = require('../../package.json');
8
+ const { version: CLI_VERSION } = require('../../../package.json');
9
9
  export function createAgentCommands({ printEnvelope, extractAgentApiKey, extractAgentKey, buildOwnerAuthHeaders }) {
10
10
  async function commandAgentRegister(ctx, flags, capabilities) {
11
11
  const ownerHeaders = buildOwnerAuthHeaders(
@@ -1,13 +1,13 @@
1
- import { requireFlag, usageError } from '../core/args.mjs';
2
- import { apiGet, apiPost } from '../core/http.mjs';
3
- import { loadProfileConfig, resolveCreditsLedger } from '../core/context.mjs';
4
- import { createCliError } from '../core/envelope.mjs';
5
- import { toAvantisSpelling } from '../core/venueBrand.mjs';
1
+ import { requireFlag, usageError } from '../../core/args.mjs';
2
+ import { apiGet, apiPost } from '../../core/http.mjs';
3
+ import { resolveCreditsLedger } from '../../core/context.mjs';
4
+ import { createCliError } from '../../core/envelope.mjs';
5
+ import { toAvantisSpelling } from '../../core/venueBrand.mjs';
6
6
  import {
7
7
  formatCreditsEstimateSummary,
8
8
  formatCreditsModelsSummary,
9
9
  stripUsdFields,
10
- } from '../lib/creditsUsdSummary.mjs';
10
+ } from '../../lib/creditsUsdSummary.mjs';
11
11
 
12
12
  function resolveToolCallsEstimate(flags) {
13
13
  const raw = flags.toolCalls ?? flags.toolCallsList;
@@ -151,14 +151,13 @@ export function createCreditsCommands({ printEnvelope, getAuthToken, buildOwnerA
151
151
  * (thirdfy-api-v2#887). The ledger follows `resolveCreditsLedger`. Agent: `POST /agent/credits/quote`
152
152
  * with the agent's key. Owner (session token or auth token): `/credits/pricing/quote`, for one of the
153
153
  * owner's agents with --agent-key. An API without the agent route (404, before #887) is quoted
154
- * through the owner route when owner auth is set and the key's agent is known: --agent-key, or the
155
- * configured agent when the key also comes from env or config. Credits only.
154
+ * through the owner route when owner auth is set and --agent-key names the key's agent. Credits only.
156
155
  */
157
156
  async function commandPricingQuote(ctx, flags) {
158
157
  const action = requireFlag(flags, 'action', 'Missing --action for pricing quote');
159
158
  // Veranta names price as their Avantis spelling, which every API deployment knows.
160
159
  const body = { actionKey: toAvantisSpelling(action), chainId: Number(flags.chainId || 8453) };
161
- const { ledger: requestedLedger, agentApiKey, agentApiKeyExplicit } = resolveCreditsLedger(flags);
160
+ const { ledger: requestedLedger, agentApiKey } = resolveCreditsLedger(flags);
162
161
  const flagAgentKey = String(flags.agentKey || '').trim();
163
162
  const ownerHeaders = () =>
164
163
  buildOwnerAuthHeaders(flags, 'Missing --owner-session-token or --auth-token (or THIRDFY_OWNER_SESSION_TOKEN / THIRDFY_AUTH_TOKEN), or an agent key, for pricing quote');
@@ -191,8 +190,9 @@ export function createCreditsCommands({ printEnvelope, getAuthToken, buildOwnerA
191
190
  { blockedStage: 'auth' },
192
191
  );
193
192
  }
194
- const pairedAgentKey = flagAgentKey || (agentApiKeyExplicit ? '' : String(process.env.THIRDFY_AGENT_KEY || loadProfileConfig()?.agent?.agentKey || '').trim());
195
- if (!pairedAgentKey) {
193
+ // Only --agent-key can name the key's agent here. The agent ledger without --agent-api-key means
194
+ // no owner auth is stored, and then the owner check above has already refused.
195
+ if (!flagAgentKey) {
196
196
  throw createCliError(
197
197
  'AGENT_IDENTITY_UNAVAILABLE',
198
198
  'This Thirdfy API has no agent quote route yet; to quote through the owner route, pass --agent-key (the agent of this API key).',
@@ -200,8 +200,8 @@ export function createCreditsCommands({ printEnvelope, getAuthToken, buildOwnerA
200
200
  );
201
201
  }
202
202
  ledger = 'owner';
203
- quotedAgentKey = pairedAgentKey;
204
- response = await ownerQuote(pairedAgentKey);
203
+ quotedAgentKey = flagAgentKey;
204
+ response = await ownerQuote(flagAgentKey);
205
205
  }
206
206
  } else {
207
207
  response = await ownerQuote(flagAgentKey);
@@ -223,8 +223,6 @@ export function createCreditsCommands({ printEnvelope, getAuthToken, buildOwnerA
223
223
  });
224
224
  }
225
225
 
226
-
227
-
228
226
  return {
229
227
  commandCreditsBuy,
230
228
  commandCreditsTransactions,
@@ -1,15 +1,14 @@
1
- import { requireFlag, usageError } from '../core/args.mjs';
2
- import { createCliError, exitAfterOutput } from '../core/envelope.mjs';
3
- import { findAgentApiKey, loadProfileConfig } from '../core/context.mjs';
4
- import { DEFAULT_CHAIN_ID, chainGasNote, isSvmChainId, parseChainIdFlag, resolveChainRpcUrl } from '../core/chainRegistry.mjs';
5
- import { apiGet } from '../core/http.mjs';
6
- import { getEffectiveRunMode } from '../core/runMode.mjs';
7
- import { readWalletControl } from '../runtime/execution/walletControl.mjs';
8
- import { blockedResultFields } from '../core/errorEnvelope.mjs';
9
- import { assertSvmChainRunByApi } from '../runtime/execution/svmLane.mjs';
10
- import { applySvmLane } from '../runtime/execution/svmLane.mjs';
11
- import { readSignedTxChainId } from '../core/signedTx.mjs';
12
- import { runNotionalWarnings } from '../runtime/risk/notional.mjs';
1
+ import { requireFlag, usageError } from '../../core/args.mjs';
2
+ import { createCliError, exitAfterOutput } from '../../core/envelope.mjs';
3
+ import { findAgentApiKey, loadProfileConfig, resolveCreditsLedger } from '../../core/context.mjs';
4
+ import { DEFAULT_CHAIN_ID, chainGasNote, isSvmChainId, parseChainIdFlag, resolveChainRpcUrl } from '../../core/chainRegistry.mjs';
5
+ import { apiGet } from '../../core/http.mjs';
6
+ import { getEffectiveRunMode } from '../../core/runMode.mjs';
7
+ import { readWalletControl } from '../../runtime/execution/walletControl.mjs';
8
+ import { blockedResultFields } from '../../core/errorEnvelope.mjs';
9
+ import { applySvmLane, assertSvmChainRunByApi } from '../../runtime/execution/svmLane.mjs';
10
+ import { readSignedTxChainId } from '../../core/execution/signedTx.mjs';
11
+ import { runNotionalWarnings } from '../../runtime/risk/notional.mjs';
13
12
 
14
13
  export function createWalletCommands(deps) {
15
14
  const {
@@ -182,12 +181,6 @@ function resolveReadinessChain(flags) {
182
181
  };
183
182
  }
184
183
 
185
- /**
186
- * The agent's execution wallet on a chain, read with its own key (`GET /agent/execution-wallet`, as
187
- * thirdfy-mcp agentWalletBootstrap): the API answer, the chain's gas note, wallet control (API 4.0),
188
- * whether it holds the funding token, and whether it can sign (`ready`). Used by `readiness` and
189
- * `wallet profile`.
190
- */
191
184
  /**
192
185
  * The agent an agent API key acts for. With an explicit --agent-api-key, only --agent-key or
193
186
  * --user-did name it: an agent from env or config may belong to another key. Otherwise the env or
@@ -196,7 +189,7 @@ function resolveReadinessChain(flags) {
196
189
  */
197
190
  function resolveAgentIdentity(flags) {
198
191
  const explicitKey = Boolean(String(flags.agentApiKey || '').trim());
199
- const agentKey = explicitKey ? String(flags.agentKey || '').trim().toLowerCase() : String(resolveAgentKey(flags) || '').trim();
192
+ const agentKey = String((explicitKey ? flags.agentKey : resolveAgentKey(flags)) || '').trim().toLowerCase();
200
193
  const explicitDid = String(flags.userDid || '').trim();
201
194
  const userDid = explicitKey
202
195
  ? explicitDid || (agentKey ? `did:wallet:${agentKey}` : '')
@@ -213,6 +206,12 @@ function resolveAgentIdentity(flags) {
213
206
  return { agentKey: agentKey || null, userDid };
214
207
  }
215
208
 
209
+ /**
210
+ * The agent's execution wallet on a chain, read with its own key (`GET /agent/execution-wallet`, as
211
+ * thirdfy-mcp agentWalletBootstrap): the API answer, the chain's gas note, wallet control (API 4.0),
212
+ * whether it holds the funding token, and whether it can sign (`ready`). Used by `readiness` and
213
+ * `wallet profile`.
214
+ */
216
215
  async function readAgentExecutionWallet(ctx, flags, agentApiKey, chainId) {
217
216
  const { agentKey, userDid } = resolveAgentIdentity(flags);
218
217
  const query = new URLSearchParams({ chainId: String(chainId), runMode: 'agent_wallet' });
@@ -236,20 +235,17 @@ async function readAgentExecutionWallet(ctx, flags, agentApiKey, chainId) {
236
235
  */
237
236
  async function commandWalletProfile(ctx, flags, capabilities) {
238
237
  const meta = { apiBase: ctx.apiBase, capabilitiesVersion: capabilities?.contractVersion || null };
239
- const ownerHeaders = (() => {
240
- try {
241
- return buildOwnerAuthHeaders(flags, 'no owner auth');
242
- } catch {
243
- return null;
244
- }
245
- })();
246
- const agentApiKey = findAgentApiKey(flags);
247
- // An owner flag the caller passed wins (as thirdfy-mcp), then an explicit --agent-api-key, then
248
- // owner auth from env or config, then an agent key from env or config.
249
- const explicitOwner = Boolean(String(flags.ownerSessionToken || flags.authToken || '').trim());
250
- const explicitAgent = Boolean(String(flags.agentApiKey || '').trim());
251
- const agentPath = !explicitOwner && (explicitAgent || (!ownerHeaders && Boolean(agentApiKey)));
252
- if (!agentPath) {
238
+ // Same precedence as the credits commands (as thirdfy-mcp): an owner flag the caller passed, then an
239
+ // explicit --agent-api-key, then owner auth from env or config, then an agent key from env or config.
240
+ const { ledger, agentApiKey } = resolveCreditsLedger(flags);
241
+ if (ledger !== 'agent') {
242
+ const ownerHeaders = (() => {
243
+ try {
244
+ return buildOwnerAuthHeaders(flags, 'no owner auth');
245
+ } catch {
246
+ return null;
247
+ }
248
+ })();
253
249
  if (!ownerHeaders) {
254
250
  throw createCliError(
255
251
  'OWNER_AUTH_REQUIRED',
@@ -1,6 +1,6 @@
1
- import { loadProfileConfig } from '../core/context.mjs';
2
- import { parseJsonFlag, requireFlag } from '../core/args.mjs';
3
- import { apiGet, apiPost } from '../core/http.mjs';
1
+ import { loadProfileConfig } from '../../core/context.mjs';
2
+ import { parseJsonFlag, requireFlag } from '../../core/args.mjs';
3
+ import { apiGet, apiPost } from '../../core/http.mjs';
4
4
 
5
5
  /**
6
6
  * The owner's side of API 4.0 wallet control (`/api/v1/agent/:agentKey/wallet-control/*`), for a
@@ -52,7 +52,7 @@ function solanaExecutionContract() {
52
52
  'Solana execution runs only with --run-mode agent_wallet on chain 101 (103 devnet where a provider supports it). self, hybrid and thirdfy stay EVM-only. Check `actions --chain-id 101` (supportedChains) for each action\'s chains.',
53
53
  };
54
54
  }
55
- export function createDiscoveryCommands({ printEnvelope, applyActionFilters, getProviderHintForActions, resolveChainSupport, getAuthToken, buildOwnerAuthHeaders, resolveAgentApiKey }) {
55
+ export function createDiscoveryCommands({ printEnvelope, applyActionFilters, getProviderHintForActions, resolveChainSupport, buildOwnerAuthHeaders, resolveAgentApiKey }) {
56
56
  async function commandCatalogsList(ctx, flags, capabilities) {
57
57
  const response = await apiGet(ctx, '/api/v1/agent/actions/catalog');
58
58
  const actions = extractActions(response);
@@ -8,8 +8,8 @@ import {
8
8
  } from '../core/runMode.mjs';
9
9
  import { apiGet } from '../core/http.mjs';
10
10
  import { applySvmLane } from '../runtime/execution/svmLane.mjs';
11
- import { isReadOnlyResolvedAction } from '../core/readOnlyActions.mjs';
12
- import { resolveWalletExecuteChainId } from '../core/walletExecuteChainId.mjs';
11
+ import { isReadOnlyResolvedAction } from '../core/execution/readOnlyActions.mjs';
12
+ import { resolveWalletExecuteChainId } from '../core/execution/walletExecuteChainId.mjs';
13
13
  import { resolveExecuteEstimatedAmountUsd } from '../runtime/execution/payloads.mjs';
14
14
  import { assertPreviewSized, buildPreviewOrder, shapeOrderPreview } from '../runtime/risk/orderPreview.mjs';
15
15
  import { actionNameForApi } from '../runtime/actions/selection.mjs';
@@ -1,10 +1,10 @@
1
- export { createPolymarketCommands, resolveConfigAgentKey } from './polymarket.mjs';
2
- export { createHyperliquidHelpers } from './hyperliquid.mjs';
3
- export { createLighterHelpers } from './lighter.mjs';
4
- export { createAvantisHelpers } from './avantis.mjs';
5
- export { createHummingbotCommands } from './hummingbot.mjs';
6
- export { createCondorCommands } from './condor.mjs';
1
+ export { createPolymarketCommands, resolveConfigAgentKey } from './venues/polymarket.mjs';
2
+ export { createHyperliquidHelpers } from './venues/hyperliquid.mjs';
3
+ export { createLighterHelpers } from './venues/lighter.mjs';
4
+ export { createAvantisHelpers } from './venues/avantis.mjs';
5
+ export { createHummingbotCommands } from './venues/hummingbot.mjs';
6
+ export { createCondorCommands } from './venues/condor.mjs';
7
7
  export { createExecuteCommands } from './execute.mjs';
8
- export { createWalletCommands } from './wallet.mjs';
9
- export { createDelegationCommands } from './delegation.mjs';
10
- export { createBootstrapCommands } from './bootstrap.mjs';
8
+ export { createWalletCommands } from './account/wallet.mjs';
9
+ export { createDelegationCommands } from './onboarding/delegation.mjs';
10
+ export { createBootstrapCommands } from './onboarding/bootstrap.mjs';
@@ -1,26 +1,26 @@
1
- import { requireFlag, isNonInteractive, usageError } from '../core/args.mjs';
2
- import { createCliError } from '../core/envelope.mjs';
3
- import { PROFILE_DEFAULTS } from '../core/constants.mjs';
1
+ import { requireFlag, isNonInteractive, usageError } from '../../core/args.mjs';
2
+ import { createCliError } from '../../core/envelope.mjs';
3
+ import { PROFILE_DEFAULTS } from '../../core/constants.mjs';
4
4
  import {
5
5
  normalizeRunMode,
6
6
  normalizeProfileName,
7
7
  normalizeCustodyMode,
8
8
  defaultCustodyModeForRunMode,
9
9
  parseBooleanFlag,
10
- } from '../core/runMode.mjs';
10
+ } from '../../core/runMode.mjs';
11
11
  import {
12
12
  loadProfileConfig,
13
13
  persistProfileConfig,
14
14
  clonePlainConfigTree,
15
15
  setNestedConfigValue,
16
16
  getProfileConfigPath,
17
- } from '../core/context.mjs';
18
- import { apiGet, apiPost, requestWithRouteFallback } from '../core/http.mjs';
19
- import { isEvmAddress, isSolanaAddress } from '../core/chainRegistry.mjs';
17
+ } from '../../core/context.mjs';
18
+ import { apiGet, apiPost, requestWithRouteFallback } from '../../core/http.mjs';
19
+ import { isEvmAddress, isSolanaAddress } from '../../core/chainRegistry.mjs';
20
20
  import { createRequire } from 'module';
21
21
 
22
22
  const require = createRequire(import.meta.url);
23
- const { version: CLI_VERSION } = require('../../package.json');
23
+ const { version: CLI_VERSION } = require('../../../package.json');
24
24
 
25
25
  export function createBootstrapCommands(deps) {
26
26
  const {
@@ -1,5 +1,5 @@
1
- import { requireFlag } from '../core/args.mjs';
2
- import { apiGet, apiPost } from '../core/http.mjs';
1
+ import { requireFlag } from '../../core/args.mjs';
2
+ import { apiGet, apiPost } from '../../core/http.mjs';
3
3
 
4
4
  /** Aligned with chat.mjs NETWORK_CHAIN_IDS and thirdfy-mcp consoleMandateChains. */
5
5
  const CONSOLE_MANDATE_NETWORK_CHAIN_IDS = {
@@ -1,12 +1,12 @@
1
1
  import { createRequire } from 'module';
2
- import { requireFlag, parseJsonFlag } from '../core/args.mjs';
3
- import { requestWithRouteFallback } from '../core/http.mjs';
4
- import { createCliError } from '../core/envelope.mjs';
5
- import { BITFINEX_PERMISSION_PROFILES, DEFAULT_BITFINEX_BASE_URL } from '../core/constants.mjs';
6
- import { parseBooleanFlag } from '../core/runMode.mjs';
2
+ import { requireFlag, parseJsonFlag } from '../../core/args.mjs';
3
+ import { requestWithRouteFallback } from '../../core/http.mjs';
4
+ import { createCliError } from '../../core/envelope.mjs';
5
+ import { BITFINEX_PERMISSION_PROFILES, DEFAULT_BITFINEX_BASE_URL } from '../../core/constants.mjs';
6
+ import { parseBooleanFlag } from '../../core/runMode.mjs';
7
7
 
8
8
  const require = createRequire(import.meta.url);
9
- const { normalizeCredentialStatus } = require('../utils/cli/delegationNormalization.cjs');
9
+ const { normalizeCredentialStatus } = require('../../utils/cli/delegationNormalization.cjs');
10
10
  export function createCredentialsCommands({ printEnvelope, getAuthToken, buildOwnerAuthHeaders, probeBitfinexPermissions }) {
11
11
  async function commandCredentialsUpsert(ctx, flags, capabilities) {
12
12
  const authToken = getAuthToken(flags, 'Missing --auth-token (or THIRDFY_AUTH_TOKEN) for credentials upsert');
@@ -1,11 +1,11 @@
1
- import { requireFlag, parseJsonFlag } from '../core/args.mjs';
2
- import { createCliError } from '../core/envelope.mjs';
3
- import { getEffectiveRunMode } from '../core/runMode.mjs';
4
- import { apiGet, apiPost, requestWithRouteFallback } from '../core/http.mjs';
1
+ import { requireFlag, parseJsonFlag } from '../../core/args.mjs';
2
+ import { createCliError } from '../../core/envelope.mjs';
3
+ import { getEffectiveRunMode } from '../../core/runMode.mjs';
4
+ import { apiGet, apiPost, requestWithRouteFallback } from '../../core/http.mjs';
5
5
  import { createRequire } from 'module';
6
6
 
7
7
  const require = createRequire(import.meta.url);
8
- const { normalizeDelegationStatus } = require('../utils/cli/delegationNormalization.cjs');
8
+ const { normalizeDelegationStatus } = require('../../utils/cli/delegationNormalization.cjs');
9
9
 
10
10
  export function createDelegationCommands(deps) {
11
11
  const {
@@ -1,4 +1,4 @@
1
- import { toLegacyVenueActionKey } from '../core/venueBrand.mjs';
1
+ import { toLegacyVenueActionKey } from '../../core/venueBrand.mjs';
2
2
 
3
3
  /**
4
4
  * Veranta (formerly Avantis) helpers. Names keep the Avantis spelling (internal identifiers); every
@@ -1,7 +1,7 @@
1
- import { apiPost } from '../core/http.mjs';
2
- import { exitAfterOutput } from '../core/envelope.mjs';
3
- import { parseJsonFlag } from '../core/args.mjs';
4
- import { negotiateCapabilities } from '../core/http.mjs';
1
+ import { apiPost } from '../../core/http.mjs';
2
+ import { exitAfterOutput } from '../../core/envelope.mjs';
3
+ import { parseJsonFlag } from '../../core/args.mjs';
4
+ import { negotiateCapabilities } from '../../core/http.mjs';
5
5
  import { resolveConfigAgentKey } from './polymarket.mjs';
6
6
 
7
7
  function agentApiKeyFromFlags(flags, ctx) {
@@ -1,7 +1,7 @@
1
- import { apiGet, apiPost } from '../core/http.mjs';
2
- import { exitAfterOutput } from '../core/envelope.mjs';
3
- import { parseJsonFlag } from '../core/args.mjs';
4
- import { negotiateCapabilities } from '../core/http.mjs';
1
+ import { apiGet, apiPost } from '../../core/http.mjs';
2
+ import { exitAfterOutput } from '../../core/envelope.mjs';
3
+ import { parseJsonFlag } from '../../core/args.mjs';
4
+ import { negotiateCapabilities } from '../../core/http.mjs';
5
5
  import { resolveConfigAgentKey } from './polymarket.mjs';
6
6
 
7
7
  function orgIdFromFlags(flags) {
@@ -1,4 +1,4 @@
1
- import { parseJsonFlag } from '../core/args.mjs';
1
+ import { parseJsonFlag } from '../../core/args.mjs';
2
2
 
3
3
  export function createHyperliquidHelpers(deps) {
4
4
  const { getPreparedParams, resolveManagedExecutionPreflight } = deps;
@@ -1,4 +1,4 @@
1
- import { parseJsonFlag } from '../core/args.mjs';
1
+ import { parseJsonFlag } from '../../core/args.mjs';
2
2
 
3
3
  export function createLighterHelpers(deps) {
4
4
  const { getPreparedParams, resolveManagedExecutionPreflight } = deps;
@@ -1,7 +1,7 @@
1
- import { loadProfileConfig } from '../core/context.mjs';
2
- import { negotiateCapabilities } from '../core/http.mjs';
3
- import { parseBooleanFlag } from '../core/runMode.mjs';
4
- import { exitAfterOutput } from '../core/envelope.mjs';
1
+ import { loadProfileConfig } from '../../core/context.mjs';
2
+ import { negotiateCapabilities } from '../../core/http.mjs';
3
+ import { parseBooleanFlag } from '../../core/runMode.mjs';
4
+ import { exitAfterOutput } from '../../core/envelope.mjs';
5
5
 
6
6
  function extractAgentKey(value) {
7
7
  if (!value || typeof value !== 'object') return '';
@@ -1,6 +1,6 @@
1
- import { apiGet, apiPost } from '../core/http.mjs';
2
- import { loadProfileConfig } from '../core/context.mjs';
3
- import { normalizeVenueProviderId } from '../core/venueBrand.mjs';
1
+ import { apiGet, apiPost } from '../../core/http.mjs';
2
+ import { loadProfileConfig } from '../../core/context.mjs';
3
+ import { normalizeVenueProviderId } from '../../core/venueBrand.mjs';
4
4
 
5
5
  // `avantis` is the internal venue id the API expects; `veranta` (the venue's new name) maps onto it.
6
6
  const VENUES = new Set(['polymarket', 'hyperliquid', 'lighter', 'avantis']);
@@ -4,4 +4,4 @@ export {
4
4
  resolveExecutionContextFromInput as resolveEarnClawAttributionFromInput,
5
5
  buildExecutionContextHeaders as buildEarnClawAttributionHeaders,
6
6
  mergeExecutionContext as mergeEarnClawContext,
7
- } from './executionContext.mjs';
7
+ } from './execution/executionContext.mjs';
@@ -1,6 +1,6 @@
1
- import { DEFAULT_TIMEOUT_MS } from './constants.mjs';
1
+ import { DEFAULT_TIMEOUT_MS } from '../constants.mjs';
2
2
  import { isReadOnlyActionName, isReadOnlyResolvedAction } from './readOnlyActions.mjs';
3
- import { toLegacyVenueActionKey } from './venueBrand.mjs';
3
+ import { toLegacyVenueActionKey } from '../venueBrand.mjs';
4
4
 
5
5
  /**
6
6
  * Default HTTP timeout for managed writes. A perps order or TP/SL update signs, broadcasts, and waits
@@ -1,4 +1,4 @@
1
- import { isSvmChainId } from './chainRegistry.mjs';
1
+ import { isSvmChainId } from '../chainRegistry.mjs';
2
2
 
3
3
  const DEFAULT_CHAIN_ID = 8453;
4
4
 
package/src/core/http.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  buildExecutionContextHeaders,
3
3
  mergeExecutionContext,
4
4
  resolveExecutionContextFromInput,
5
- } from './executionContext.mjs';
5
+ } from './execution/executionContext.mjs';
6
6
 
7
7
  function sleep(ms) {
8
8
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -2,7 +2,7 @@ import { createCliError } from '../../core/envelope.mjs';
2
2
  import {
3
3
  HOSTED_RUNTIME_IDEMPOTENCY_NAMESPACE,
4
4
  readHostedRuntimeUuid,
5
- } from '../../core/hostedRuntimeIdempotency.mjs';
5
+ } from '../../core/execution/hostedRuntimeIdempotency.mjs';
6
6
 
7
7
  const POLYMARKET_PLACE_ACTIONS = new Set([
8
8
  'place_polymarket_order',
@@ -1,14 +1,14 @@
1
1
  import { randomUUID } from 'crypto';
2
- import { wrapWriteIdempotencyKeyForHostedRuntime } from '../../core/hostedRuntimeIdempotency.mjs';
3
- import { resolveExecutionContextFromEnv } from '../../core/executionContext.mjs';
2
+ import { wrapWriteIdempotencyKeyForHostedRuntime } from '../../core/execution/hostedRuntimeIdempotency.mjs';
3
+ import { resolveExecutionContextFromEnv } from '../../core/execution/executionContext.mjs';
4
4
  import { requireFlag, parseJsonFlag } from '../../core/args.mjs';
5
5
  import { findAgentApiKey, loadProfileConfig } from '../../core/context.mjs';
6
6
  import { createCliError } from '../../core/envelope.mjs';
7
7
  import { toLegacyVenueActionKey } from '../../core/venueBrand.mjs';
8
8
  import { normalizeRunMode, normalizeManagedRunMode, normalizeHybridWalletMode } from '../../core/runMode.mjs';
9
9
  import { assertHostedRuntimePolymarketWriteIdempotency } from './hostedRuntimeWriteGate.mjs';
10
- import { resolveTokenInForFunding } from '../../core/fundingTokenIn.mjs';
11
- import { resolveWalletExecuteChainId } from '../../core/walletExecuteChainId.mjs';
10
+ import { resolveTokenInForFunding } from '../../core/execution/fundingTokenIn.mjs';
11
+ import { resolveWalletExecuteChainId } from '../../core/execution/walletExecuteChainId.mjs';
12
12
 
13
13
  function isTruthyFlag(value) {
14
14
  return value === true || String(value || '').trim().toLowerCase() === 'true';