@thirdfy/agent-cli 0.5.0 → 0.5.1
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
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@thirdfy/agent-cli` are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
4
|
|
|
5
|
+
## [0.5.1] - 2026-10-16
|
|
6
|
+
|
|
7
|
+
A patch release: `doctor certify execution` works for agents with a narrow allowlist.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **`doctor certify execution` no longer fails on venue writes outside the agent's allowlist** (THI-201). With an agent key, the CLI reads the agent's own action list, so bare certification flagged every venue write the agent may not call (for example `place_hyperliquid_tp_sl` or `update_lighter_leverage`) as `CATALOG_SCHEMA_UNAVAILABLE` and failed. It now checks only the venue writes the agent may call and lists the rest in `skippedVenueActions`. An allowed action with a broken schema, a `--required-actions` entry the agent can't call, and a public catalog missing a venue write all still fail.
|
|
12
|
+
|
|
5
13
|
## [0.5.0] - 2026-10-15
|
|
6
14
|
|
|
7
15
|
`thirdfy-agent login` signs in with OAuth in the browser (auth.thirdfy.com, the same sign-in the MCP uses), as one agent with read access, plus trade with `--trade`. A minor version because `login` without a token flag now starts that sign-in instead of failing, and `credits balance` / `pricing quote` drop their credit counts for USD. `login email`, token flags and agent API keys work as before.
|
package/README.md
CHANGED
|
@@ -39,12 +39,11 @@ Run without global install:
|
|
|
39
39
|
npx @thirdfy/agent-cli --help
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
## What's new in v0.5.
|
|
42
|
+
## What's new in v0.5.1
|
|
43
43
|
|
|
44
|
-
-
|
|
45
|
-
- **
|
|
46
|
-
-
|
|
47
|
-
- Older versions: see [CHANGELOG.md](./CHANGELOG.md).
|
|
44
|
+
- **`doctor certify execution` passes for agents with a narrow allowlist.** It now checks only the venue writes your agent may call, and lists the others under `skippedVenueActions` instead of failing. Runtimes that stop on a failed certify (Hermes, OpenClaw) start again.
|
|
45
|
+
- **Still fails closed:** an allowed action with a broken schema, a `--required-actions` entry the agent can't call, or a missing catalog.
|
|
46
|
+
- Browser sign-in (`thirdfy-agent login`, `--trade` for writes) arrived in 0.5.0. Older versions: see [CHANGELOG.md](./CHANGELOG.md).
|
|
48
47
|
|
|
49
48
|
## Quick start
|
|
50
49
|
|
package/package.json
CHANGED
package/src/commands/doctor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'module';
|
|
2
2
|
import { requireFlag } from '../core/args.mjs';
|
|
3
3
|
import { apiGet, requestWithRouteFallback } from '../core/http.mjs';
|
|
4
|
-
import { loadProfileConfig, getProfileConfigPath,
|
|
4
|
+
import { loadProfileConfig, getProfileConfigPath, getCachedActionsCatalogSnapshot } from '../core/context.mjs';
|
|
5
5
|
import { DEFAULT_API_BASE, PROFILE_DEFAULTS } from '../core/constants.mjs';
|
|
6
6
|
import { DEFAULT_CHAIN_ID, describeChainGas, parseChainIdFlag, pinnedRpcProvider, resolveChainRpcUrl } from '../core/chainRegistry.mjs';
|
|
7
7
|
import { exitAfterOutput } from '../core/envelope.mjs';
|
|
@@ -333,9 +333,12 @@ async function commandManagedSetup(ctx, flags, capabilities) {
|
|
|
333
333
|
|
|
334
334
|
async function commandDoctorCertifyExecution(ctx, flags) {
|
|
335
335
|
let liveActions = null;
|
|
336
|
+
let catalogPolicyScoped = false;
|
|
336
337
|
let catalogError = null;
|
|
337
338
|
try {
|
|
338
|
-
|
|
339
|
+
const snapshot = await getCachedActionsCatalogSnapshot(ctx, flags);
|
|
340
|
+
liveActions = snapshot.actions;
|
|
341
|
+
catalogPolicyScoped = snapshot.policyScoped === true;
|
|
339
342
|
} catch (error) {
|
|
340
343
|
catalogError = {
|
|
341
344
|
message: error?.message || 'Actions catalog fetch failed',
|
|
@@ -356,6 +359,7 @@ async function commandDoctorCertifyExecution(ctx, flags) {
|
|
|
356
359
|
runMode,
|
|
357
360
|
expectedSchemaDigest,
|
|
358
361
|
requiredActions,
|
|
362
|
+
catalogPolicyScoped,
|
|
359
363
|
});
|
|
360
364
|
|
|
361
365
|
printEnvelope({
|
|
@@ -369,6 +373,7 @@ async function commandDoctorCertifyExecution(ctx, flags) {
|
|
|
369
373
|
catalog: {
|
|
370
374
|
fetched: Array.isArray(liveActions),
|
|
371
375
|
actionCount: Array.isArray(liveActions) ? liveActions.length : 0,
|
|
376
|
+
policyScoped: catalogPolicyScoped,
|
|
372
377
|
error: catalogError,
|
|
373
378
|
},
|
|
374
379
|
},
|
|
@@ -227,6 +227,7 @@ export function buildExecutionCertificationReport({
|
|
|
227
227
|
runMode = null,
|
|
228
228
|
expectedSchemaDigest = null,
|
|
229
229
|
requiredActions = [],
|
|
230
|
+
catalogPolicyScoped = false,
|
|
230
231
|
} = {}) {
|
|
231
232
|
const version = String(cliVersion || PACKAGE_VERSION).trim();
|
|
232
233
|
const normalizedRequiredActions = parseRequiredActions(requiredActions);
|
|
@@ -259,10 +260,25 @@ export function buildExecutionCertificationReport({
|
|
|
259
260
|
}
|
|
260
261
|
}
|
|
261
262
|
|
|
263
|
+
// A keyed catalog lists only the agent's allowlist. Bare certification then checks the venue
|
|
264
|
+
// writes this agent may call; the rest are reported as skipped, not as missing schemas.
|
|
265
|
+
// An unscoped (public) catalog that lacks a venue action still fails closed.
|
|
266
|
+
const scopeToAllowlist = bareCertification && catalogFetched && catalogPolicyScoped === true;
|
|
267
|
+
const liveActionKeys = new Set();
|
|
268
|
+
for (const row of liveActions || []) {
|
|
269
|
+
for (const name of [row?.action, ...(Array.isArray(row?.aliases) ? row.aliases : [])]) {
|
|
270
|
+
if (name) liveActionKeys.add(normalizeActionKey(String(name)));
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const skippedVenueActions = [];
|
|
262
274
|
const venueActionNames =
|
|
263
275
|
normalizedRequiredActions.length > 0
|
|
264
276
|
? normalizedRequiredActions.filter((action) => isWriteAction(action))
|
|
265
|
-
: VENUE_WRITE_ACTION_FIXTURES.map((fixture) => fixture.action)
|
|
277
|
+
: VENUE_WRITE_ACTION_FIXTURES.map((fixture) => fixture.action).filter((action) => {
|
|
278
|
+
if (!scopeToAllowlist || liveActionKeys.has(normalizeActionKey(action))) return true;
|
|
279
|
+
skippedVenueActions.push({ action, reason: 'NOT_ON_AGENT_ALLOWLIST' });
|
|
280
|
+
return false;
|
|
281
|
+
});
|
|
266
282
|
|
|
267
283
|
const venueActions = runSchemaCompatibilityChecks(catalogByAction, venueActionNames, {
|
|
268
284
|
requireLiveCatalog: bareCertification,
|
|
@@ -380,6 +396,7 @@ export function buildExecutionCertificationReport({
|
|
|
380
396
|
commandAvailability,
|
|
381
397
|
authorityInputs,
|
|
382
398
|
venueActions,
|
|
399
|
+
skippedVenueActions,
|
|
383
400
|
checks,
|
|
384
401
|
};
|
|
385
402
|
}
|