@deeeed/metamask-harness 0.90.0 → 0.91.0
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 +16 -0
- package/dist/commands/check.js +18 -20
- package/library/actions/core/perps/_controller.mjs +1 -19
- package/library/actions/extension/perps/perps.mjs +1 -11
- package/library/actions/extension/ui/navigate.mjs +27 -2
- package/library/actions/mobile/perps/perps.mjs +1 -7
- package/library/actions/shared/perps/item-side.mjs +18 -0
- package/library/manifests/core.action-manifest.json +6 -1
- package/library/manifests/extension.action-manifest.json +8 -2
- package/library/manifests/mobile.action-manifest.json +13 -3
- package/library/manifests/web-dapp.action-manifest.json +38 -0
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.91.0 - 2026-10-12
|
|
6
|
+
|
|
7
|
+
- Support Extension `ui.navigate page=settings` through the visible account menu and verify the Settings page before returning.
|
|
8
|
+
|
|
9
|
+
- Declare bounded `watch_logs.timeout_ms` for Core, Mobile, Extension and web-dapp, including Terminal inheritance. Use the supporting protocol 0.40.0 and runner 0.31.0 through coordinated runtime pins.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Breaking correction inherited from runner 0.31.0: run-scoped log observations require paths resolved before producers execute; output-derived paths must use `scope=file`. Nested output assertions and static JSON paths now receive complete preflight validation.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Run the declared Oxlint script for changed-source checks and explicit fixes instead of skipping lint when ESLint is absent.
|
|
18
|
+
|
|
19
|
+
- Mobile Perps position selectors now enforce long/short selection when the controller returns signed size without a side label. Core and Extension reuse the same side normalization while preserving their existing selection rules.
|
|
20
|
+
|
|
5
21
|
## 0.90.0 - 2026-10-12
|
|
6
22
|
|
|
7
23
|
- Use typed iOS simulator recording targets, retain original Android recording segments, and use the shared action-context snapshot API for Extension evidence.
|
package/dist/commands/check.js
CHANGED
|
@@ -62,34 +62,32 @@ async function handleCheck(argv) {
|
|
|
62
62
|
});
|
|
63
63
|
const policyFailed = suppressionCheck.status === "fail";
|
|
64
64
|
const fixes = [];
|
|
65
|
-
const
|
|
65
|
+
const usesOxlint = typeof packageJson?.scripts?.["lint:oxlint"] === "string";
|
|
66
|
+
const lintCommandArgs = usesOxlint ? ["lint:oxlint"] : resolveEslintConfigArgs(packageJson);
|
|
67
|
+
const lintCacheArgs = usesOxlint ? [] : ["--cache", "--cache-location", path.join(artifactsDir, "eslintcache")];
|
|
68
|
+
const lintCheck = {
|
|
69
|
+
id: usesOxlint ? "oxlint" : "eslint",
|
|
70
|
+
label: usesOxlint ? "Changed-file Oxlint" : "Changed-file ESLint",
|
|
71
|
+
target,
|
|
72
|
+
artifactsDir,
|
|
73
|
+
files: existingChangedFiles.filter((file) => JS_TS_EXT_RE.test(file)),
|
|
74
|
+
command: usesOxlint ? "yarn" : executable(target, "eslint"),
|
|
75
|
+
args: [...lintCommandArgs, ...lintCacheArgs]
|
|
76
|
+
};
|
|
66
77
|
if (fix && !policyFailed) {
|
|
67
78
|
fixes.push(
|
|
68
79
|
runToolCheck({
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
files: existingChangedFiles.filter((file) => JS_TS_EXT_RE.test(file)),
|
|
74
|
-
command: executable(target, "eslint"),
|
|
75
|
-
args: [...eslintConfigArgs, "--fix", "--cache", "--cache-location", path.join(artifactsDir, "eslintcache")]
|
|
80
|
+
...lintCheck,
|
|
81
|
+
id: `${lintCheck.id}-fix`,
|
|
82
|
+
label: `${lintCheck.label} fix`,
|
|
83
|
+
args: [...lintCommandArgs, "--fix", ...lintCacheArgs]
|
|
76
84
|
})
|
|
77
85
|
);
|
|
78
86
|
fixes.push(runFormatterFix({ target, artifactsDir, files: existingChangedFiles.filter((file) => FORMAT_EXT_RE.test(file)) }));
|
|
79
87
|
}
|
|
80
88
|
const checks = [suppressionCheck];
|
|
81
89
|
if (!policyFailed) {
|
|
82
|
-
checks.push(
|
|
83
|
-
runToolCheck({
|
|
84
|
-
id: "eslint",
|
|
85
|
-
label: "Changed-file ESLint",
|
|
86
|
-
target,
|
|
87
|
-
artifactsDir,
|
|
88
|
-
files: existingChangedFiles.filter((file) => JS_TS_EXT_RE.test(file)),
|
|
89
|
-
command: executable(target, "eslint"),
|
|
90
|
-
args: [...eslintConfigArgs, "--cache", "--cache-location", path.join(artifactsDir, "eslintcache")]
|
|
91
|
-
})
|
|
92
|
-
);
|
|
90
|
+
checks.push(runToolCheck(lintCheck));
|
|
93
91
|
checks.push(runFormatterCheck({ target, artifactsDir, files: existingChangedFiles.filter((file) => FORMAT_EXT_RE.test(file)) }));
|
|
94
92
|
checks.push(
|
|
95
93
|
...runJestChecks({
|
|
@@ -115,7 +113,7 @@ async function handleCheck(argv) {
|
|
|
115
113
|
}
|
|
116
114
|
const status = [...fixes, ...checks].some((check) => check.status === "fail") ? "fail" : "pass";
|
|
117
115
|
const exitCode = status === "pass" ? EXIT.ok : EXIT.validation;
|
|
118
|
-
const guidance = policyFailed ? ["Remove the newly added eslint-disable directive(s). Fix the underlying violation with existing named styles, project tokens, or another established source pattern; then rerun mm-harness check diff [--fix]. Other checks were skipped until this policy failure is removed."] : checks.some((check) => check.id ===
|
|
116
|
+
const guidance = policyFailed ? ["Remove the newly added eslint-disable directive(s). Fix the underlying violation with existing named styles, project tokens, or another established source pattern; then rerun mm-harness check diff [--fix]. Other checks were skipped until this policy failure is removed."] : checks.some((check) => check.id === lintCheck.id && check.status === "fail") ? ["Fix the reported violations in changed source using existing project patterns and tokens; do not suppress rules, hide violations behind indirection, weaken configuration, or bypass check diff. Then rerun mm-harness check diff [--fix]."] : [];
|
|
119
117
|
const failureUserAction = guidance[0] ?? `inspect ${path.join(artifactsDir, "validation-summary.json")}, fix the failing check, then retry: mm-harness check diff --target ${shellQuote(target)} --base ${shellQuote(baseRef)} --profile ${profile} --json`;
|
|
120
118
|
const summary = {
|
|
121
119
|
schemaVersion: 1,
|
|
@@ -6,6 +6,7 @@ import path from 'node:path';
|
|
|
6
6
|
import { pathToFileURL } from 'node:url';
|
|
7
7
|
|
|
8
8
|
import { walletFixturePath } from '../../harness-exports.mjs';
|
|
9
|
+
import { normalizeSide, sideForItem } from '../../shared/perps/item-side.mjs';
|
|
9
10
|
import { readFixtureAccounts } from '../../shared/wallet/fixture-accounts.mjs';
|
|
10
11
|
import { createRewardsClient, rewardsApiUrl } from './_rewards.mjs';
|
|
11
12
|
|
|
@@ -597,25 +598,6 @@ export function symbolForItem(item) {
|
|
|
597
598
|
return normalizeMarketSymbol(item?.symbol ?? item?.coin ?? '');
|
|
598
599
|
}
|
|
599
600
|
|
|
600
|
-
// Orders carry buy/sell sides; Position.size is signed and authoritative.
|
|
601
|
-
function normalizeSide(rawSide) {
|
|
602
|
-
const side = String(rawSide ?? '').toLowerCase();
|
|
603
|
-
if (side === 'buy' || side === 'b') return 'long';
|
|
604
|
-
if (side === 'sell' || side === 'a' || side === 's') return 'short';
|
|
605
|
-
return side;
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
function sideForItem(item, itemType) {
|
|
609
|
-
if (itemType === 'position') {
|
|
610
|
-
const rawSize = item?.size ?? item?.szi;
|
|
611
|
-
if (typeof rawSize !== 'string' && typeof rawSize !== 'number') return '';
|
|
612
|
-
const size = Number(rawSize);
|
|
613
|
-
if (!Number.isFinite(size) || size === 0) return '';
|
|
614
|
-
return size > 0 ? 'long' : 'short';
|
|
615
|
-
}
|
|
616
|
-
return normalizeSide(item?.side ?? item?.direction ?? '');
|
|
617
|
-
}
|
|
618
|
-
|
|
619
601
|
function uniqueSymbols(symbols) {
|
|
620
602
|
return Array.from(new Set(symbols.filter(Boolean)));
|
|
621
603
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Implement Extension Perps state reads, UI setup and funded trade operations.
|
|
2
2
|
// Funded paths check runtime identity and retain mutation receipts for cleanup.
|
|
3
3
|
|
|
4
|
+
import { sideForItem } from '../../shared/perps/item-side.mjs';
|
|
4
5
|
import { pathToFileURL } from 'node:url';
|
|
5
6
|
import { createHash } from 'node:crypto';
|
|
6
7
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
@@ -66,17 +67,6 @@ function symbolForItem(item) {
|
|
|
66
67
|
return normalizeMarketSymbol(item?.coin ?? item?.symbol ?? '');
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
function sideForItem(item) {
|
|
70
|
-
const side = String(item?.side ?? item?.direction ?? '').toLowerCase();
|
|
71
|
-
if (side === 'buy' || side === 'b') return 'long';
|
|
72
|
-
if (side === 'sell' || side === 'a' || side === 's') return 'short';
|
|
73
|
-
if (side) return side;
|
|
74
|
-
// Positions carry no side, only a signed size (long > 0, short < 0).
|
|
75
|
-
const size = Number(item?.size ?? item?.szi);
|
|
76
|
-
if (Number.isFinite(size) && size !== 0) return size > 0 ? 'long' : 'short';
|
|
77
|
-
return side;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
70
|
function uniqueSymbols(symbols) {
|
|
81
71
|
return Array.from(new Set(symbols.filter(Boolean)));
|
|
82
72
|
}
|
|
@@ -46,7 +46,7 @@ function text(value) {
|
|
|
46
46
|
function pageIntent(node) {
|
|
47
47
|
const page = text(node?.page);
|
|
48
48
|
if (!page) return undefined;
|
|
49
|
-
if (page === 'back' || page === 'home' || page === 'perps' || page === 'swap') return { page };
|
|
49
|
+
if (page === 'back' || page === 'home' || page === 'perps' || page === 'swap' || page === 'settings') return { page };
|
|
50
50
|
if (page === 'perps-market-list' || page === 'perps-activity') return { page };
|
|
51
51
|
if (page === 'network') {
|
|
52
52
|
const network = text(node.network);
|
|
@@ -61,7 +61,7 @@ function pageIntent(node) {
|
|
|
61
61
|
if (!market) throw new Error('extension ui.navigate page=perps-market requires market or symbol.');
|
|
62
62
|
return { page, market };
|
|
63
63
|
}
|
|
64
|
-
throw new Error('extension ui.navigate supported page intents: back, home, network, perps, perps-market-list, perps-market, perps-activity, swap.');
|
|
64
|
+
throw new Error('extension ui.navigate supported page intents: back, home, settings, network, perps, perps-market-list, perps-market, perps-activity, swap.');
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
async function goBack(page, timeoutMs) {
|
|
@@ -503,6 +503,27 @@ export async function openNetwork(page, network, chainId, addIfMissing, timeoutM
|
|
|
503
503
|
throw new Error(`Network ${network} (${chainId}) did not become the selected wallet filter.`);
|
|
504
504
|
}
|
|
505
505
|
|
|
506
|
+
export async function openSettings(page, timeoutMs) {
|
|
507
|
+
const destination = dataTestId('parent-selector-settings-page');
|
|
508
|
+
if (await hasVisibleSelector(page, destination)) {
|
|
509
|
+
return { method: 'visible-ui', href: await currentHref(page), steps: [] };
|
|
510
|
+
}
|
|
511
|
+
const deadline = Date.now() + timeoutMs;
|
|
512
|
+
const menu = dataTestId('account-options-menu-button');
|
|
513
|
+
const settings = dataTestId('global-menu-settings');
|
|
514
|
+
const steps = [];
|
|
515
|
+
if (!(await hasVisibleSelector(page, settings))) {
|
|
516
|
+
await page.waitFor({ selector: menu, expected: 'visible', timeoutMs: Math.max(1, deadline - Date.now()) });
|
|
517
|
+
await activateSemanticControl(page, menu);
|
|
518
|
+
steps.push(menu);
|
|
519
|
+
}
|
|
520
|
+
await page.waitFor({ selector: settings, expected: 'visible', timeoutMs: Math.max(1, deadline - Date.now()) });
|
|
521
|
+
const navigation = await activateSemanticControl(page, settings);
|
|
522
|
+
steps.push(settings);
|
|
523
|
+
await page.waitFor({ selector: destination, expected: 'visible', timeoutMs: Math.max(1, deadline - Date.now()) });
|
|
524
|
+
return { navigation, method: 'visible-ui', href: await currentHref(page), selector: settings, steps };
|
|
525
|
+
}
|
|
526
|
+
|
|
506
527
|
export async function openSwap(page, timeoutMs) {
|
|
507
528
|
const sourceAmount = dataTestId('from-amount');
|
|
508
529
|
const sourceToken = dataTestId('bridge-source-button');
|
|
@@ -588,6 +609,10 @@ export async function navigateExtensionUi(input) {
|
|
|
588
609
|
);
|
|
589
610
|
return { action: input.action, ...intent, ...result, proofPath: 'ui-navigation' };
|
|
590
611
|
}
|
|
612
|
+
if (intent.page === 'settings') {
|
|
613
|
+
const result = await openSettings(page, timeoutMs);
|
|
614
|
+
return { action: input.action, ...intent, ...result, proofPath: 'ui-navigation' };
|
|
615
|
+
}
|
|
591
616
|
if (intent.page === 'swap') {
|
|
592
617
|
const result = await openSwap(page, timeoutMs);
|
|
593
618
|
return { action: input.action, ...intent, ...result, proofPath: 'ui-navigation' };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Implement Mobile Perps navigation, trading mutations, assertions, and setup or cleanup through the bridge.
|
|
2
2
|
// Strategy getters used during cleanup can settle tracked collateral.
|
|
3
|
+
import { sideForItem } from '../../shared/perps/item-side.mjs';
|
|
3
4
|
import { pathToFileURL } from 'node:url';
|
|
4
5
|
import {
|
|
5
6
|
MOBILE_BRIDGE_RESULT_ERROR_CODES,
|
|
@@ -300,13 +301,6 @@ function symbolForItem(item) {
|
|
|
300
301
|
return normalizeMarketSymbol(item?.symbol ?? item?.coin ?? '');
|
|
301
302
|
}
|
|
302
303
|
|
|
303
|
-
function sideForItem(item) {
|
|
304
|
-
const side = String(item?.side ?? item?.direction ?? '').toLowerCase();
|
|
305
|
-
if (side === 'buy' || side === 'b') return 'long';
|
|
306
|
-
if (side === 'sell' || side === 'a' || side === 's') return 'short';
|
|
307
|
-
return side;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
304
|
function configuredSymbols(input, items) {
|
|
311
305
|
const selector = input.node?.selector && typeof input.node.selector === 'object' ? input.node.selector : {};
|
|
312
306
|
const mode = String(input.node?.mode ?? selector.mode ?? 'matching').toLowerCase();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Normalize explicit order sides and the signed sizes returned for Perps positions.
|
|
2
|
+
export function normalizeSide(rawSide) {
|
|
3
|
+
const side = String(rawSide ?? '').toLowerCase();
|
|
4
|
+
if (side === 'buy' || side === 'b') return 'long';
|
|
5
|
+
if (side === 'sell' || side === 'a' || side === 's') return 'short';
|
|
6
|
+
return side;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function sideForItem(item, itemType) {
|
|
10
|
+
if (itemType !== 'position') {
|
|
11
|
+
const side = normalizeSide(item?.side ?? item?.direction);
|
|
12
|
+
if (side || itemType !== undefined) return side;
|
|
13
|
+
}
|
|
14
|
+
const rawSize = item?.size ?? item?.szi;
|
|
15
|
+
if (typeof rawSize !== 'string' && typeof rawSize !== 'number') return '';
|
|
16
|
+
const size = Number(rawSize);
|
|
17
|
+
return Number.isFinite(size) && size !== 0 ? (size > 0 ? 'long' : 'short') : '';
|
|
18
|
+
}
|
|
@@ -362,7 +362,7 @@
|
|
|
362
362
|
}
|
|
363
363
|
},
|
|
364
364
|
"watch_logs": {
|
|
365
|
-
"description": "
|
|
365
|
+
"description": "Observe log text immediately or within a declared timeout_ms window.",
|
|
366
366
|
"examples": [
|
|
367
367
|
{
|
|
368
368
|
"action": "watch_logs",
|
|
@@ -386,6 +386,11 @@
|
|
|
386
386
|
"run",
|
|
387
387
|
"file"
|
|
388
388
|
]
|
|
389
|
+
},
|
|
390
|
+
"timeout_ms": {
|
|
391
|
+
"type": "integer",
|
|
392
|
+
"minimum": 0,
|
|
393
|
+
"description": "Observation window from 0 through 60000 ms; a positive window requires nonempty contains."
|
|
389
394
|
}
|
|
390
395
|
},
|
|
391
396
|
"required": [
|
|
@@ -342,7 +342,7 @@
|
|
|
342
342
|
}
|
|
343
343
|
},
|
|
344
344
|
"watch_logs": {
|
|
345
|
-
"description": "
|
|
345
|
+
"description": "Observe log text immediately or within a declared timeout_ms window.",
|
|
346
346
|
"examples": [
|
|
347
347
|
{
|
|
348
348
|
"action": "watch_logs",
|
|
@@ -366,6 +366,11 @@
|
|
|
366
366
|
"run",
|
|
367
367
|
"file"
|
|
368
368
|
]
|
|
369
|
+
},
|
|
370
|
+
"timeout_ms": {
|
|
371
|
+
"type": "integer",
|
|
372
|
+
"minimum": 0,
|
|
373
|
+
"description": "Observation window from 0 through 60000 ms; a positive window requires nonempty contains."
|
|
369
374
|
}
|
|
370
375
|
},
|
|
371
376
|
"required": [
|
|
@@ -509,7 +514,8 @@
|
|
|
509
514
|
"perps-market-list",
|
|
510
515
|
"perps-market",
|
|
511
516
|
"perps-activity",
|
|
512
|
-
"swap"
|
|
517
|
+
"swap",
|
|
518
|
+
"settings"
|
|
513
519
|
]
|
|
514
520
|
},
|
|
515
521
|
"market": {
|
|
@@ -345,7 +345,7 @@
|
|
|
345
345
|
}
|
|
346
346
|
},
|
|
347
347
|
"watch_logs": {
|
|
348
|
-
"description": "
|
|
348
|
+
"description": "Observe log text immediately or within a declared timeout_ms window.",
|
|
349
349
|
"examples": [
|
|
350
350
|
{
|
|
351
351
|
"action": "watch_logs",
|
|
@@ -365,10 +365,20 @@
|
|
|
365
365
|
},
|
|
366
366
|
"scope": {
|
|
367
367
|
"type": "string",
|
|
368
|
-
"enum": [
|
|
368
|
+
"enum": [
|
|
369
|
+
"run",
|
|
370
|
+
"file"
|
|
371
|
+
]
|
|
372
|
+
},
|
|
373
|
+
"timeout_ms": {
|
|
374
|
+
"type": "integer",
|
|
375
|
+
"minimum": 0,
|
|
376
|
+
"description": "Observation window from 0 through 60000 ms; a positive window requires nonempty contains."
|
|
369
377
|
}
|
|
370
378
|
},
|
|
371
|
-
"required": [
|
|
379
|
+
"required": [
|
|
380
|
+
"path"
|
|
381
|
+
],
|
|
372
382
|
"additionalProperties": false
|
|
373
383
|
}
|
|
374
384
|
},
|
|
@@ -1097,6 +1097,44 @@
|
|
|
1097
1097
|
},
|
|
1098
1098
|
"additionalProperties": false
|
|
1099
1099
|
}
|
|
1100
|
+
},
|
|
1101
|
+
"watch_logs": {
|
|
1102
|
+
"description": "Observe log text immediately or within a declared timeout_ms window.",
|
|
1103
|
+
"examples": [
|
|
1104
|
+
{
|
|
1105
|
+
"action": "watch_logs",
|
|
1106
|
+
"path": "logs/app.log",
|
|
1107
|
+
"intent": "Observe the runtime behavior needed for this proof.",
|
|
1108
|
+
"next": "done"
|
|
1109
|
+
}
|
|
1110
|
+
],
|
|
1111
|
+
"schema": {
|
|
1112
|
+
"type": "object",
|
|
1113
|
+
"properties": {
|
|
1114
|
+
"path": {
|
|
1115
|
+
"type": "string"
|
|
1116
|
+
},
|
|
1117
|
+
"contains": {
|
|
1118
|
+
"type": "string"
|
|
1119
|
+
},
|
|
1120
|
+
"scope": {
|
|
1121
|
+
"type": "string",
|
|
1122
|
+
"enum": [
|
|
1123
|
+
"run",
|
|
1124
|
+
"file"
|
|
1125
|
+
]
|
|
1126
|
+
},
|
|
1127
|
+
"timeout_ms": {
|
|
1128
|
+
"type": "integer",
|
|
1129
|
+
"minimum": 0,
|
|
1130
|
+
"description": "Observation window from 0 through 60000 ms; a positive window requires nonempty contains."
|
|
1131
|
+
}
|
|
1132
|
+
},
|
|
1133
|
+
"required": [
|
|
1134
|
+
"path"
|
|
1135
|
+
],
|
|
1136
|
+
"additionalProperties": false
|
|
1137
|
+
}
|
|
1100
1138
|
}
|
|
1101
1139
|
}
|
|
1102
1140
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deeeed/metamask-harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.91.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mm-harness": "bin/mm-harness"
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"check:syntax": "find . -name '*.mjs' -print0 | xargs -0 -n1 node --check"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@farmslot/adapter-node": "0.1.
|
|
25
|
-
"@farmslot/adapter-rn": "0.20.
|
|
26
|
-
"@farmslot/adapter-sdk": "0.9.
|
|
27
|
-
"@farmslot/adapter-web": "0.7.
|
|
28
|
-
"@farmslot/agent-runtime": "0.18.
|
|
24
|
+
"@farmslot/adapter-node": "0.1.14",
|
|
25
|
+
"@farmslot/adapter-rn": "0.20.1",
|
|
26
|
+
"@farmslot/adapter-sdk": "0.9.1",
|
|
27
|
+
"@farmslot/adapter-web": "0.7.1",
|
|
28
|
+
"@farmslot/agent-runtime": "0.18.1",
|
|
29
29
|
"@farmslot/handoff": "^0.3.1",
|
|
30
|
-
"@farmslot/protocol": "0.
|
|
31
|
-
"@farmslot/recipe-cli": "0.14.
|
|
32
|
-
"@farmslot/recipe-runner": "0.
|
|
30
|
+
"@farmslot/protocol": "0.40.0",
|
|
31
|
+
"@farmslot/recipe-cli": "0.14.2",
|
|
32
|
+
"@farmslot/recipe-runner": "0.31.0",
|
|
33
33
|
"agent-device": "0.19.3",
|
|
34
34
|
"commander": "^12.0.0",
|
|
35
35
|
"esbuild": "0.28.1",
|