@thirdfy/agent-cli 0.2.7 → 0.2.8

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,16 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.2.8] - 2026-06-13
8
+
9
+ ### Added
10
+
11
+ - EarnClaw runtime attribution on all API POSTs: reads `THIRDFY_EXECUTION_RUNTIME_ID` / `THIRDFY_EXECUTION_ORG_ID` (with `EARNCLAW_*` fallback) and sends `executionContext` plus `x-thirdfy-execution-*` headers on execute paths. Pairs with Thirdfy API v3.4.55+ for per-runtime credit debits.
12
+
13
+ ### Fixed
14
+
15
+ - `apiPost` resolves execution context headers from the request body, not env only.
16
+
7
17
  ## [0.2.7] - 2026-06-08
8
18
 
9
19
  ### Added
package/README.md CHANGED
@@ -40,11 +40,11 @@ Run without global install:
40
40
  npx @thirdfy/agent-cli --help
41
41
  ```
42
42
 
43
- ## What's new in v0.2.7
43
+ ## What's new in v0.2.8
44
44
 
45
- - Hyperliquid `update_hyperliquid_leverage` sets per-coin leverage (cross by default) before placing an order; bounded by the venue per-coin maxLeverage.
46
- - The leverage update is an offchain venue write: run it with `--run-mode thirdfy`, `--run-mode hybrid`, or `--run-mode agent_wallet` (not `self`/BYOW).
47
- - Provider hints list `update_hyperliquid_leverage` in Hyperliquid order management actions.
45
+ - Hosted runtimes can set `THIRDFY_EXECUTION_RUNTIME_ID` and `THIRDFY_EXECUTION_ORG_ID` in machine env (EarnClaw also sets legacy `EARNCLAW_*` aliases). The CLI forwards neutral `executionContext` on Thirdfy API POSTs.
46
+ - Attribution uses `x-thirdfy-execution-runtime-id`, `x-thirdfy-execution-org-id`, and `executionContext` on execute payloads.
47
+ - Pairs with Thirdfy API v3.4.55+ and EarnClaw cost sync `attribution=strict`.
48
48
 
49
49
  Older versions: [CHANGELOG.md](./CHANGELOG.md) and [GitHub Releases](https://github.com/thirdfy/agent-cli/releases).
50
50
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thirdfy/agent-cli",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Thirdfy Agent CLI for onboarding, governance preflight, execute-intent, and status polling.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,7 @@
1
+ /** @deprecated Import from executionContext.mjs instead. */
2
+ export {
3
+ resolveExecutionContextFromEnv as resolveEarnClawAttributionFromEnv,
4
+ resolveExecutionContextFromInput as resolveEarnClawAttributionFromInput,
5
+ buildExecutionContextHeaders as buildEarnClawAttributionHeaders,
6
+ mergeExecutionContext as mergeEarnClawContext,
7
+ } from './executionContext.mjs';
@@ -0,0 +1,50 @@
1
+ function readUuid(value) {
2
+ const trimmed = String(value || '').trim();
3
+ 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)
4
+ ? trimmed
5
+ : undefined;
6
+ }
7
+
8
+ export function resolveExecutionContextFromEnv() {
9
+ const runtimeId = readUuid(process.env.THIRDFY_EXECUTION_RUNTIME_ID)
10
+ || readUuid(process.env.EARNCLAW_RUNTIME_ID);
11
+ const orgId = readUuid(process.env.THIRDFY_EXECUTION_ORG_ID)
12
+ || readUuid(process.env.EARNCLAW_ORG_ID);
13
+ return { runtimeId, orgId };
14
+ }
15
+
16
+ export function resolveExecutionContextFromInput(input = {}) {
17
+ const env = resolveExecutionContextFromEnv();
18
+ const executionContext = input.executionContext && typeof input.executionContext === 'object'
19
+ ? input.executionContext
20
+ : {};
21
+ const context = input.context && typeof input.context === 'object' ? input.context : {};
22
+ const runtimeId = readUuid(input.runtimeId)
23
+ || readUuid(executionContext.runtimeId)
24
+ || readUuid(context.runtimeId)
25
+ || env.runtimeId;
26
+ const orgId = readUuid(input.orgId)
27
+ || readUuid(executionContext.orgId)
28
+ || readUuid(context.orgId)
29
+ || env.orgId;
30
+ return { runtimeId, orgId };
31
+ }
32
+
33
+ export function buildExecutionContextHeaders(attribution) {
34
+ const headers = {};
35
+ if (attribution.runtimeId) headers['x-thirdfy-execution-runtime-id'] = attribution.runtimeId;
36
+ if (attribution.orgId) headers['x-thirdfy-execution-org-id'] = attribution.orgId;
37
+ return headers;
38
+ }
39
+
40
+ export function mergeExecutionContext(body) {
41
+ const attribution = resolveExecutionContextFromInput(body);
42
+ if (!attribution.runtimeId && !attribution.orgId) return body;
43
+ const executionContext = body.executionContext && typeof body.executionContext === 'object'
44
+ ? { ...body.executionContext }
45
+ : {};
46
+ if (attribution.runtimeId && !executionContext.runtimeId) executionContext.runtimeId = attribution.runtimeId;
47
+ if (attribution.orgId && !executionContext.orgId) executionContext.orgId = attribution.orgId;
48
+ if (!executionContext.source) executionContext.source = 'hosted_runtime';
49
+ return { ...body, executionContext };
50
+ }
package/src/core/http.mjs CHANGED
@@ -1,15 +1,30 @@
1
+ import {
2
+ buildExecutionContextHeaders,
3
+ mergeExecutionContext,
4
+ resolveExecutionContextFromInput,
5
+ } from './executionContext.mjs';
6
+
1
7
  export async function apiGet(ctx, route, headers = {}) {
2
- return requestJson(ctx, route, { method: 'GET', headers });
8
+ return requestJson(ctx, route, { method: 'GET', headers: mergeExecutionContextHeaders(headers) });
9
+ }
10
+
11
+ function mergeExecutionContextHeaders(headers = {}, body = {}) {
12
+ return {
13
+ ...buildExecutionContextHeaders(resolveExecutionContextFromInput(body)),
14
+ ...headers,
15
+ };
3
16
  }
4
17
 
5
18
  export async function apiPost(ctx, route, body, headers = {}) {
19
+ const normalizedBody = body && typeof body === 'object' ? body : {};
20
+ const mergedBody = mergeExecutionContext(normalizedBody);
6
21
  return requestJson(ctx, route, {
7
22
  method: 'POST',
8
23
  headers: {
9
24
  'content-type': 'application/json',
10
- ...headers,
25
+ ...mergeExecutionContextHeaders(headers, normalizedBody),
11
26
  },
12
- body: JSON.stringify(body),
27
+ body: JSON.stringify(mergedBody),
13
28
  });
14
29
  }
15
30