@thirdfy/agent-cli 0.2.38 → 0.2.40
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,18 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.2.40] - 2026-07-27
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- EarnClaw runtime Polymarket write gate: when `EARNCLAW_RUNTIME_ID` or `THIRDFY_EXECUTION_RUNTIME_ID` is set, `place_polymarket_order` / `place_prediction_order` require `idempotencyKey` starting with `earnclaw:<runtimeId>`. Blocks bare CLI/dashboard tool buys on managed Hermes machines. MCP parity in `thirdfy-mcp` **0.0.83**.
|
|
12
|
+
|
|
13
|
+
## [0.2.39] - 2026-07-27
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Morpho provider hints: `supportedChains` `[8453, 4663]`; Base MetaMorpho V1 writable, Robinhood Vault V2 read-only until deposit capacity opens. Updated `docs/providers/earn-morpho.md`. Pairs with Thirdfy API develop + `thirdfy-mcp` **0.0.82**.
|
|
18
|
+
|
|
7
19
|
## [0.2.38] - 2026-07-25
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/README.md
CHANGED
|
@@ -40,13 +40,11 @@ Run without global install:
|
|
|
40
40
|
npx @thirdfy/agent-cli --help
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
## What's new in v0.2.
|
|
43
|
+
## What's new in v0.2.40
|
|
44
|
+
- EarnClaw machines: Polymarket place orders require an `earnclaw:<runtimeId>…` idempotency key (blocks ad-hoc CLI/dashboard buys).
|
|
45
|
+
- Pack execute-gate and operator exits already set this key; bare tool writes fail closed.
|
|
46
|
+
- See [CHANGELOG.md](./CHANGELOG.md) for older versions.
|
|
44
47
|
|
|
45
|
-
- Earn discovery prefers `get_earning_opportunities` / `get-earning-opportunities` (legacy `get_earn_opportunities` aliases remain).
|
|
46
|
-
- Lighter onboarding hints: repeat `complete_lighter_onboarding` on Base (`8453`) until setup is ready.
|
|
47
|
-
- Pairs with MCP **0.0.81** and Thirdfy API **v3.13.26**.
|
|
48
|
-
|
|
49
|
-
Older versions: see [CHANGELOG.md](./CHANGELOG.md) and [GitHub Releases](https://github.com/thirdfy/agent-cli/releases).
|
|
50
48
|
|
|
51
49
|
## Quick start
|
|
52
50
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createCliError } from '../../core/envelope.mjs';
|
|
2
|
+
|
|
3
|
+
function readUuid(value) {
|
|
4
|
+
const trimmed = String(value || '').trim();
|
|
5
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(trimmed)
|
|
6
|
+
? trimmed
|
|
7
|
+
: undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const POLYMARKET_PLACE_ACTIONS = new Set([
|
|
11
|
+
'place_polymarket_order',
|
|
12
|
+
'place-polymarket-order',
|
|
13
|
+
'place_prediction_order',
|
|
14
|
+
'place-prediction-order',
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
export function resolveEarnclawRuntimeId(env = process.env) {
|
|
18
|
+
const runtimeId = readUuid(env.THIRDFY_EXECUTION_RUNTIME_ID)
|
|
19
|
+
|| readUuid(env.EARNCLAW_RUNTIME_ID);
|
|
20
|
+
return runtimeId ? runtimeId.toLowerCase() : '';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function normalizePolymarketPlaceAction(action) {
|
|
24
|
+
return String(action || '')
|
|
25
|
+
.trim()
|
|
26
|
+
.toLowerCase()
|
|
27
|
+
.replace(/_/g, '-');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function isPolymarketPlaceAction(action) {
|
|
31
|
+
const key = String(action || '').trim().toLowerCase();
|
|
32
|
+
if (POLYMARKET_PLACE_ACTIONS.has(key)) return true;
|
|
33
|
+
return normalizePolymarketPlaceAction(key) === 'place-polymarket-order'
|
|
34
|
+
|| normalizePolymarketPlaceAction(key) === 'place-prediction-order';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* On EarnClaw-managed Hermes machines, ad-hoc CLI/MCP/dashboard tool calls can
|
|
39
|
+
* place Polymarket orders without pack execute-gate. Require an earnclaw-scoped
|
|
40
|
+
* idempotency key so only adapter/operator keys pass.
|
|
41
|
+
*/
|
|
42
|
+
export function assertEarnclawPolymarketWriteIdempotency({
|
|
43
|
+
action,
|
|
44
|
+
idempotencyKey,
|
|
45
|
+
paramsIdempotencyKey,
|
|
46
|
+
env = process.env,
|
|
47
|
+
} = {}) {
|
|
48
|
+
if (!isPolymarketPlaceAction(action)) return null;
|
|
49
|
+
const runtimeId = resolveEarnclawRuntimeId(env);
|
|
50
|
+
if (!runtimeId) return null;
|
|
51
|
+
|
|
52
|
+
const prefix = `earnclaw:${runtimeId}`;
|
|
53
|
+
const keys = [idempotencyKey, paramsIdempotencyKey]
|
|
54
|
+
.map((key) => String(key || '').trim())
|
|
55
|
+
.filter(Boolean);
|
|
56
|
+
if (keys.some((key) => key.toLowerCase().startsWith(prefix))) return null;
|
|
57
|
+
|
|
58
|
+
throw createCliError(
|
|
59
|
+
'EARNCLAW_PM_IDEMPOTENCY_REQUIRED',
|
|
60
|
+
`EarnClaw runtime ${runtimeId} requires Polymarket place orders to use idempotencyKey starting with "${prefix}". ` +
|
|
61
|
+
'Pack execute-gate and operator exits set this automatically. Bare CLI/dashboard tool writes are blocked.',
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -3,6 +3,7 @@ import { requireFlag, parseJsonFlag } from '../../core/args.mjs';
|
|
|
3
3
|
import { loadProfileConfig } from '../../core/context.mjs';
|
|
4
4
|
import { createCliError } from '../../core/envelope.mjs';
|
|
5
5
|
import { normalizeRunMode, normalizeManagedRunMode, normalizeHybridWalletMode } from '../../core/runMode.mjs';
|
|
6
|
+
import { assertEarnclawPolymarketWriteIdempotency } from './earnclawRuntimeWriteGate.mjs';
|
|
6
7
|
export function createExecutionPayloads({ getPreparedParams, rawUnitsToDecimalString }) {
|
|
7
8
|
function buildBuildTxPayload(flags, resolvedAction) {
|
|
8
9
|
const runMode = String(flags.runMode || '').trim().toLowerCase() || 'self';
|
|
@@ -125,6 +126,11 @@ function buildManagedExecutePayload(flags, options) {
|
|
|
125
126
|
} else if (flags.idempotencyKey) {
|
|
126
127
|
payload.executionIdempotencyKey = String(flags.idempotencyKey);
|
|
127
128
|
}
|
|
129
|
+
assertEarnclawPolymarketWriteIdempotency({
|
|
130
|
+
action: payload.action,
|
|
131
|
+
idempotencyKey: payload.executionIdempotencyKey,
|
|
132
|
+
paramsIdempotencyKey: managedParams?.idempotencyKey,
|
|
133
|
+
});
|
|
128
134
|
return payload;
|
|
129
135
|
}
|
|
130
136
|
|
|
@@ -171,6 +177,13 @@ function buildIntentPayload(flags, options) {
|
|
|
171
177
|
} else if (flags.idempotencyKey) {
|
|
172
178
|
payload.idempotencyKey = String(flags.idempotencyKey);
|
|
173
179
|
}
|
|
180
|
+
if (!options.validationOnly) {
|
|
181
|
+
assertEarnclawPolymarketWriteIdempotency({
|
|
182
|
+
action: payload.action,
|
|
183
|
+
idempotencyKey: payload.idempotencyKey,
|
|
184
|
+
paramsIdempotencyKey: payload.params?.idempotencyKey,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
174
187
|
return payload;
|
|
175
188
|
}
|
|
176
189
|
|
|
@@ -392,10 +392,11 @@ export function createProviderHints({ getNegotiatedCapabilitiesCache }) {
|
|
|
392
392
|
canonicalWriteAction: 'deposit_earn_position',
|
|
393
393
|
readActions: ['get_morpho_vaults', 'get_earn_provider', 'get_earn_position'],
|
|
394
394
|
orderManagementActions: ['deposit_earn_position', 'withdraw_earn_position'],
|
|
395
|
-
supportedChains: [8453,
|
|
396
|
-
laneCompatibility:
|
|
395
|
+
supportedChains: [8453, 4663],
|
|
396
|
+
laneCompatibility:
|
|
397
|
+
'Base MetaMorpho V1 vaults are writable (use depositPlan from discovery). Robinhood Vault V2 on 4663 is discoverable read-only until maxDeposit > 0. Deposits require ERC-20 approval before deposit_earn_position.',
|
|
397
398
|
example:
|
|
398
|
-
'thirdfy-agent
|
|
399
|
+
'thirdfy-agent run --action get_earn_opportunities --params \'{"providerId":"morpho","chainId":8453,"asset":"USDC"}\' && thirdfy-agent run --action deposit_earn_position --params \'{"providerId":"morpho","chainId":8453,"vaultAddress":"0x...","tokenAddress":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"0.1","tokenDecimals":6}\'',
|
|
399
400
|
};
|
|
400
401
|
}
|
|
401
402
|
if (provider === 'aegis') {
|