@deeeed/metamask-harness 0.78.0 → 0.80.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 +55 -0
- package/README.md +1 -1
- package/adapters/extension/ensure-browser.sh +2 -2
- package/adapters/extension/inject.mjs +0 -1
- package/adapters/extension/launch-browser.cjs +39 -613
- package/adapters/extension/readiness.mjs +2 -5
- package/adapters/extension/reattach.sh +2 -2
- package/adapters/extension/stamp-runtime-title.cjs +1 -1
- package/adapters/manifest.json +2 -34
- package/adapters/mobile/bridge-runtime/cdp-bridge.cjs +57 -1358
- package/adapters/mobile/bridge-runtime/teaching.cjs +20 -0
- package/adapters/mobile/inject.sh +16 -0
- package/adapters/mobile/launch-console-forwarder.cjs +1 -2
- package/adapters/mobile/open-device.sh +2 -2
- package/adapters/mobile/reload-app.mjs +4 -4
- package/adapters/mobile/reset-app-data.sh +1 -1
- package/adapters/mobile/start-console-forwarder.sh +3 -2
- package/adapters/mobile/start-metro.sh +17 -12
- package/adapters/mobile/wait-for-bridge.cjs +2 -2
- package/adapters/shared/ensure-runner-deps.sh +2 -2
- package/adapters/shared/harness-source-fingerprint.mjs +13 -8
- package/adapters/shared/open-debug.mjs +2 -2
- package/adapters/shared/runner-deps-ready.mjs +1 -1
- package/adapters/shared/sync-wallet-fixture.sh +8 -5
- package/adapters/terminal/cleanup.mjs +2 -1
- package/adapters/terminal/inject.mjs +2 -1
- package/adapters/terminal/lib/cdp-client.mjs +1 -1
- package/bin/mm-harness +9 -28
- package/dist/adapters/checkout-files.js +16 -0
- package/dist/adapters/console-capture.js +14 -1
- package/dist/adapters/core/actions.js +4 -3
- package/dist/adapters/core/overlay.js +1 -1
- package/dist/adapters/core/readiness.js +28 -1
- package/dist/adapters/core/run.js +3 -3
- package/dist/adapters/core/surface.js +22 -5
- package/dist/adapters/extension/browser-pid.js +56 -0
- package/dist/adapters/extension/console-capture.js +1 -1
- package/dist/adapters/extension/doctor-checks.js +1 -1
- package/dist/adapters/extension/ensure-ready.js +5 -4
- package/dist/adapters/extension/extension-id.js +1 -1
- package/dist/adapters/extension/feature-flags.js +1 -1
- package/dist/adapters/extension/fixtures.js +1 -2
- package/dist/adapters/extension/launch.js +4 -5
- package/dist/adapters/extension/launched-browser.js +1 -2
- package/dist/adapters/extension/network-observer.js +1 -1
- package/dist/adapters/extension/overlay.js +1 -1
- package/dist/adapters/extension/product-config.js +1 -1
- package/dist/adapters/extension/readiness.js +1 -1
- package/dist/adapters/extension/reload.js +1 -1
- package/dist/adapters/extension/run.js +24 -10
- package/dist/adapters/extension/runtime-decision.js +3 -2
- package/dist/adapters/extension/runtime.js +9 -5
- package/dist/adapters/extension/surface.js +20 -5
- package/dist/adapters/extension/verify.js +2 -2
- package/dist/adapters/harness-freshness.js +2 -1
- package/dist/adapters/mobile/android-gfxinfo-performance.js +1 -3
- package/dist/adapters/mobile/app-identity.js +10 -0
- package/dist/adapters/mobile/doctor-checks.js +1 -1
- package/dist/adapters/mobile/fixtures.js +1 -1
- package/dist/adapters/mobile/launch.js +27 -28
- package/dist/adapters/mobile/lifecycle.js +1 -1
- package/dist/adapters/mobile/metro-env.js +9 -59
- package/dist/adapters/mobile/performance-observer.js +1 -1
- package/dist/adapters/mobile/prepare-target.js +1 -1
- package/dist/adapters/mobile/prepare.js +4 -5
- package/dist/adapters/mobile/provision.js +1 -1
- package/dist/adapters/mobile/readiness.js +1 -1
- package/dist/adapters/mobile/recording-target.js +15 -0
- package/dist/adapters/mobile/release-artifact-state.js +1 -1
- package/dist/adapters/mobile/reload.js +1 -1
- package/dist/adapters/mobile/run.js +9 -8
- package/dist/adapters/mobile/runtime-decision.js +5 -7
- package/dist/adapters/mobile/source-freshness.js +22 -126
- package/dist/adapters/mobile/surface.js +31 -6
- package/dist/adapters/mobile/ui.js +16 -5
- package/dist/adapters/mobile/verify.js +2 -3
- package/dist/adapters/performance/cdp-trace.js +1 -1
- package/dist/adapters/performance/device-platform.js +1 -1
- package/dist/adapters/registry.js +2 -14
- package/dist/adapters/slot-ports.js +1 -1
- package/dist/adapters/surface.js +1 -0
- package/dist/adapters/terminal/console-capture.js +1 -1
- package/dist/adapters/terminal/launch.js +1 -1
- package/dist/adapters/terminal/run.js +25 -2
- package/dist/adapters/terminal/surface.js +12 -4
- package/dist/adapters.js +8 -4
- package/dist/advisor-policy.js +1 -1
- package/dist/checkout-view.js +1 -2
- package/dist/cli.js +28 -15
- package/dist/command-contract.js +1 -26
- package/dist/commands/call.js +10 -24
- package/dist/commands/check.js +3 -4
- package/dist/commands/checklist.js +1 -1
- package/dist/commands/completion-candidates.js +2 -10
- package/dist/commands/config.js +2 -2
- package/dist/commands/core-readiness.js +12 -7
- package/dist/commands/debug.js +3 -3
- package/dist/commands/device-target.js +5 -5
- package/dist/commands/doctor.js +2 -14
- package/dist/commands/domain.js +2 -2
- package/dist/commands/ensure-ready.js +1 -7
- package/dist/commands/fixtures.js +5 -6
- package/dist/commands/help.js +3 -4
- package/dist/commands/launch/device.js +10 -17
- package/dist/commands/launch/extension.js +3 -9
- package/dist/commands/launch/mobile.js +1 -1
- package/dist/commands/list-executables.js +1 -3
- package/dist/commands/logs.js +3 -3
- package/dist/commands/manifest.js +1 -12
- package/dist/commands/mobile-device-view.js +4 -2
- package/dist/commands/overlay.js +110 -0
- package/dist/commands/pin.js +1 -1
- package/dist/commands/pr-body.js +2 -2
- package/dist/commands/prepare.js +6 -11
- package/dist/commands/provision.js +3 -12
- package/dist/commands/recipe-advice.js +1 -2
- package/dist/commands/recipe-quality.js +2 -3
- package/dist/commands/resolve-extension.js +1 -7
- package/dist/commands/review.js +4 -4
- package/dist/commands/run-engine.js +12 -51
- package/dist/commands/run.js +4 -25
- package/dist/commands/runtime-decision.js +1 -6
- package/dist/commands/runtime-health.js +1 -7
- package/dist/commands/runtime-launch.js +1 -13
- package/dist/commands/self-test.js +2 -6
- package/dist/commands/status-watch.js +1 -2
- package/dist/commands/status.js +2 -5
- package/dist/commands/task-init.js +2 -3
- package/dist/commands/tutorial.js +2 -2
- package/dist/commands/update.js +1 -1
- package/dist/completions-cache.js +1 -1
- package/dist/console-classifier.js +19 -0
- package/dist/discovery.js +1 -1
- package/dist/doctor.js +3 -4
- package/dist/funding-execution-context.js +15 -1
- package/dist/host.js +32 -0
- package/dist/index.js +1 -6
- package/dist/live-tsx.js +49 -0
- package/dist/mm-harness-cli.js +2 -4
- package/dist/network-observation.js +4 -4
- package/dist/paths.js +48 -78
- package/dist/performance-observation.js +2 -2
- package/dist/progress.js +1 -1
- package/dist/recipe-assistance-context.js +2 -4
- package/dist/recipe-security.js +2 -59
- package/dist/review/knowledge.js +3 -3
- package/dist/runner.js +5 -3
- package/dist/runtime-context.js +1 -1
- package/dist/task-view.js +3 -4
- package/docs/CONTRIBUTING.md +3 -3
- package/docs/cli-contract.md +2 -2
- package/docs/feature-guard.md +90 -0
- package/library/README.md +3 -1
- package/library/actions/core/perps/_controller.mjs +153 -130
- package/library/actions/core/perps/quote_fees.mjs +58 -0
- package/library/actions/core/wallet/_fixture-accounts.mjs +69 -0
- package/library/actions/core/wallet/list_accounts.mjs +14 -57
- package/library/actions/extension/feature_flags/state.mjs +1 -1
- package/library/actions/extension/platform/cdp.mjs +2 -8
- package/library/actions/harness-exports.mjs +1 -6
- package/library/actions/mobile/app/network-control.mjs +6 -8
- package/library/actions/mobile/perps/prepare_local_snapshot_endpoint.mjs +1 -1
- package/library/actions/mobile/platform/bridge.mjs +8 -8
- package/library/actions/mobile/platform/native-session-name.mjs +21 -1
- package/library/actions/mobile/platform/native-session.mjs +3 -4
- package/library/actions/mobile/platform/observe-ui.mjs +12 -6
- package/library/actions/mobile/ui/native-navigation.mjs +4 -3
- package/library/actions/mobile/wallet/native-ui.mjs +3 -2
- package/library/actions/shared/analytics/_adapter.mjs +1 -1
- package/library/actions/shared/console-findings.mjs +1 -1
- package/library/actions/terminal/platform/runtime.mjs +2 -1
- package/library/manifests/core.action-manifest.json +83 -13
- package/package.json +8 -8
- package/adapters/extension/lib/slot-title.cjs +0 -292
- package/adapters/mobile/bridge-runtime/console-forwarder.cjs +0 -472
- package/adapters/mobile/bridge-runtime/lib/bridge-errors.cjs +0 -125
- package/adapters/mobile/bridge-runtime/lib/cdp-broker.cjs +0 -1055
- package/adapters/mobile/bridge-runtime/lib/cdp-eval.cjs +0 -110
- package/adapters/mobile/bridge-runtime/lib/config.cjs +0 -61
- package/adapters/mobile/bridge-runtime/lib/console-format.cjs +0 -53
- package/adapters/mobile/bridge-runtime/lib/devtools-proxy.cjs +0 -177
- package/adapters/mobile/bridge-runtime/lib/issue-capture.cjs +0 -446
- package/adapters/mobile/bridge-runtime/lib/match-bridge-target.cjs +0 -84
- package/adapters/mobile/bridge-runtime/lib/target-discovery.cjs +0 -403
- package/adapters/mobile/bridge-runtime/lib/ws-client.cjs +0 -116
- package/adapters/mobile/coalesce-metro-log.cjs +0 -24
- package/adapters/mobile/launch-metro.cjs +0 -77
- package/adapters/mobile/metro-config.cjs +0 -98
- package/adapters/mobile/metro-log-generation.cjs +0 -106
- package/dist/adapters/mobile/frame-metrics.js +0 -118
- package/dist/adapters/mobile/video-recorder.js +0 -289
- package/dist/artifact-files.js +0 -92
- package/dist/checkout-lock.js +0 -149
- package/dist/cli-color.js +0 -98
- package/dist/command-journal.js +0 -308
- package/dist/commands/last.js +0 -60
- package/dist/commands/launch/index.js +0 -109
- package/dist/commands/parse-args.js +0 -279
- package/dist/commands/reload.js +0 -41
- package/dist/commands/run-report.js +0 -241
- package/dist/commands/shared.js +0 -323
- package/dist/commands/stop.js +0 -60
- package/dist/devices.js +0 -100
- package/dist/execution-provenance.js +0 -332
- package/dist/harness.js +0 -451
- package/dist/heal-bounds.js +0 -137
- package/dist/json-stream.js +0 -60
- package/dist/leaf-invoke.js +0 -19
- package/dist/library-provenance.js +0 -33
- package/dist/live-adapter-contract.js +0 -380
- package/dist/recording-target.js +0 -120
- package/dist/run-diagnostics.js +0 -364
- package/dist/run-recording.js +0 -481
- package/dist/runtime-proof.js +0 -90
- package/library/actions/mobile/platform/tool-paths.mjs +0 -123
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Bridge from library actions to the harness path
|
|
1
|
+
// Bridge from library actions to the harness path helpers. Published
|
|
2
2
|
// installs load the compiled dist (node cannot type-strip .ts under
|
|
3
3
|
// node_modules); source checkouts without dist fall back to src. Deliberately
|
|
4
4
|
// narrow — importing the package entry here would close an import cycle
|
|
@@ -14,20 +14,15 @@ async function load(distRelative, srcRelative) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const paths = await load('dist/paths.js', 'src/paths.ts');
|
|
17
|
-
const recording = await load('dist/run-recording.js', 'src/run-recording.ts');
|
|
18
17
|
const featureFlags = await load('dist/feature-flags.js', 'src/feature-flags.ts');
|
|
19
18
|
|
|
20
19
|
export const {
|
|
21
20
|
importRecipeHarnessRuntimeBrowserExtension,
|
|
22
21
|
importRecipeHarnessRuntimeCdp,
|
|
23
22
|
extensionIdPath,
|
|
24
|
-
recipeHarnessPath,
|
|
25
|
-
recipeRuntimeDir,
|
|
26
23
|
walletFixturePath,
|
|
27
24
|
} = paths;
|
|
28
25
|
|
|
29
|
-
export const { captureActiveRecipeRecordingSnapshot } = recording;
|
|
30
|
-
|
|
31
26
|
// One normalisation for --remote-flag specs, fixture objects, and the
|
|
32
27
|
// doctor/status summary line. See src/feature-flags.ts.
|
|
33
28
|
export const {
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
import { execFile } from 'node:child_process';
|
|
4
4
|
import { promisify } from 'node:util';
|
|
5
5
|
|
|
6
|
-
import { resolveMobileToolPath } from '
|
|
6
|
+
import { resolveMobileToolPath } from '@farmslot/adapter-rn';
|
|
7
|
+
|
|
8
|
+
import { nativeAppId } from '../platform/native-session-name.mjs';
|
|
7
9
|
|
|
8
10
|
const execFileAsync = promisify(execFile);
|
|
9
11
|
|
|
@@ -31,13 +33,9 @@ function selectedAndroidSerial(input) {
|
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
function selectedAndroidPackage(input) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
input.context?.env?.ANDROID_PACKAGE_ID ??
|
|
38
|
-
process.env.ANDROID_PACKAGE_ID ??
|
|
39
|
-
'io.metamask',
|
|
40
|
-
).trim();
|
|
36
|
+
const explicit = input.node?.package_id ?? input.node?.app_id;
|
|
37
|
+
if (explicit != null) return String(explicit).trim();
|
|
38
|
+
return nativeAppId({ ...process.env, ...(input.context?.env ?? {}) }, 'android');
|
|
41
39
|
}
|
|
42
40
|
|
|
43
41
|
async function defaultRun(file, args) {
|
|
@@ -4,7 +4,7 @@ import { execFile } from 'node:child_process';
|
|
|
4
4
|
import { promisify } from 'node:util';
|
|
5
5
|
|
|
6
6
|
import { runAdapter } from '../platform/bridge.mjs';
|
|
7
|
-
import { resolveMobileToolPath } from '
|
|
7
|
+
import { resolveMobileToolPath } from '@farmslot/adapter-rn';
|
|
8
8
|
|
|
9
9
|
const execFileAsync = promisify(execFile);
|
|
10
10
|
|
|
@@ -8,10 +8,10 @@ import { promisify } from 'node:util';
|
|
|
8
8
|
import os from 'node:os';
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
import { fileURLToPath } from 'node:url';
|
|
11
|
-
import bridgeErrors from '
|
|
12
|
-
import brokerModule from '
|
|
13
|
-
import configModule from '
|
|
14
|
-
import { resolveMobileToolPath } from '
|
|
11
|
+
import bridgeErrors from '@farmslot/adapter-rn/bridge-runtime/lib/bridge-errors.cjs';
|
|
12
|
+
import brokerModule from '@farmslot/recipe-runner/cdp-broker';
|
|
13
|
+
import configModule from '@farmslot/adapter-rn/bridge-runtime/lib/config.cjs';
|
|
14
|
+
import { resolveMobileToolPath } from '@farmslot/adapter-rn';
|
|
15
15
|
|
|
16
16
|
const {
|
|
17
17
|
BRIDGE_ERROR_CODES,
|
|
@@ -155,8 +155,8 @@ export async function bridgeEnv(input) {
|
|
|
155
155
|
...(input.context?.env || {}),
|
|
156
156
|
CDP_TIMEOUT: String(input.node?.cdp_timeout_ms ?? process.env.CDP_TIMEOUT ?? '10000'),
|
|
157
157
|
};
|
|
158
|
-
if (adbPath) env.
|
|
159
|
-
if (idbPath) env.
|
|
158
|
+
if (adbPath) env.RECIPE_RN_ADB_PATH = adbPath;
|
|
159
|
+
if (idbPath) env.RECIPE_RN_IDB_PATH = idbPath;
|
|
160
160
|
const target = resolveMobileTarget(input);
|
|
161
161
|
const requestedPlatform = target.requestedPlatform;
|
|
162
162
|
const watcherPort = target.watcherPort;
|
|
@@ -238,8 +238,8 @@ export function resolveMobileTarget(input) {
|
|
|
238
238
|
input.node?.sim_udid ?? contextEnv.SIM_UDID ?? process.env.SIM_UDID;
|
|
239
239
|
const configuredPlatform = String(
|
|
240
240
|
input.node?.platform ??
|
|
241
|
-
contextEnv.
|
|
242
|
-
process.env.
|
|
241
|
+
contextEnv.RECIPE_RN_EXPLICIT_PLATFORM ??
|
|
242
|
+
process.env.RECIPE_RN_EXPLICIT_PLATFORM ??
|
|
243
243
|
contextEnv.PLATFORM ??
|
|
244
244
|
process.env.PLATFORM ??
|
|
245
245
|
'',
|
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
// Derive native session names and device-specific state directories, honoring configured overrides.
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// The host adapter supplies the app under test in the action env
|
|
5
|
+
// (ANDROID_PACKAGE_ID / IOS_BUNDLE_ID, display name in
|
|
6
|
+
// METAMASK_RECIPE_MOBILE_APP_LABEL); the library has no default app.
|
|
7
|
+
export function nativeAppId(env, platform) {
|
|
8
|
+
const key = platform === 'android' ? 'ANDROID_PACKAGE_ID' : 'IOS_BUNDLE_ID';
|
|
9
|
+
const app = String(env[key] ?? '').trim();
|
|
10
|
+
if (!app) {
|
|
11
|
+
throw new Error(`Mobile native UI needs the app identity in ${key}. Next: run through mm-harness run or call, or set ${key}.`);
|
|
12
|
+
}
|
|
13
|
+
return app;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function nativeAppLabel(env) {
|
|
17
|
+
const label = String(env.METAMASK_RECIPE_MOBILE_APP_LABEL ?? '').trim();
|
|
18
|
+
if (!label) {
|
|
19
|
+
throw new Error('Mobile native UI needs the app display name in METAMASK_RECIPE_MOBILE_APP_LABEL. Next: run through mm-harness run or call, or set METAMASK_RECIPE_MOBILE_APP_LABEL.');
|
|
20
|
+
}
|
|
21
|
+
return label;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function nativeSessionName(env, device, app) {
|
|
5
25
|
const configured = String(env.METAMASK_RECIPE_MOBILE_SESSION ?? '').trim();
|
|
6
26
|
const source = configured || `mm-harness-${app}-${device}`;
|
|
7
27
|
return source.replace(/[^A-Za-z0-9._-]/gu, '-').slice(0, 120);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Create device-targeted native UI sessions for actions and accessibility snapshots.
|
|
2
2
|
// Opening an instrumented iOS session hides the accessibility-masking HUD.
|
|
3
|
-
import { createAgentDeviceUiTransport } from '@farmslot/
|
|
3
|
+
import { createAgentDeviceUiTransport } from '@farmslot/adapter-rn';
|
|
4
4
|
import { createAgentDeviceClient } from 'agent-device';
|
|
5
5
|
|
|
6
6
|
import { resolveMobileTarget } from './bridge.mjs';
|
|
@@ -8,6 +8,7 @@ import { hideAccessibilityMaskingHud } from './observe-ui.mjs';
|
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
nativeAgentDeviceStateDir,
|
|
11
|
+
nativeAppId,
|
|
11
12
|
nativeSessionName,
|
|
12
13
|
} from './native-session-name.mjs';
|
|
13
14
|
|
|
@@ -19,9 +20,7 @@ export function createNativeSession(input, domain, sessionSuffix = '') {
|
|
|
19
20
|
? target.adbSerial ?? ''
|
|
20
21
|
: input.node?.sim_udid ?? env.SIM_UDID ?? target.iosSimulator ?? '').trim();
|
|
21
22
|
if (!device) throw new Error(`Mobile ${domain} native actions require one explicit ${platform} device. Next: pass --device <device>.`);
|
|
22
|
-
const app =
|
|
23
|
-
? env.ANDROID_PACKAGE_ID ?? 'io.metamask'
|
|
24
|
-
: env.IOS_BUNDLE_ID ?? 'io.metamask.MetaMask');
|
|
23
|
+
const app = nativeAppId(env, platform);
|
|
25
24
|
const baseSession = nativeSessionName(env, device, app);
|
|
26
25
|
const session = sessionSuffix
|
|
27
26
|
? `${baseSession}-${String(sessionSuffix).replace(/[^A-Za-z0-9._-]/gu, '-')}`.slice(0, 120)
|
|
@@ -7,9 +7,11 @@ import { createAgentDeviceClient } from 'agent-device';
|
|
|
7
7
|
import { bridgeCommand } from './bridge.mjs';
|
|
8
8
|
import {
|
|
9
9
|
nativeAgentDeviceStateDir,
|
|
10
|
+
nativeAppId,
|
|
11
|
+
nativeAppLabel,
|
|
10
12
|
nativeSessionName,
|
|
11
13
|
} from './native-session-name.mjs';
|
|
12
|
-
import { mobileToolRecovery, resolveMobileToolPath } from '
|
|
14
|
+
import { mobileToolRecovery, resolveMobileToolPath } from '@farmslot/adapter-rn';
|
|
13
15
|
|
|
14
16
|
const execFileAsync = promisify(execFile);
|
|
15
17
|
const VISIBLE_LIMIT = 200;
|
|
@@ -93,8 +95,13 @@ async function readNativeHierarchy(payload, context) {
|
|
|
93
95
|
env.METAMASK_RECIPE_PROJECT_ROOT = String(context.projectRoot);
|
|
94
96
|
}
|
|
95
97
|
const platform = resolvePlatform(node, env);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
const appLabel = nativeAppLabel(env);
|
|
99
|
+
const hierarchy = platform === 'android'
|
|
100
|
+
? await readAndroidHierarchy(node, env)
|
|
101
|
+
: await readIosHierarchy(node, env);
|
|
102
|
+
// No screen name and no labelled item: name the screen after the app.
|
|
103
|
+
hierarchy.screen.name ??= appLabel;
|
|
104
|
+
return hierarchy;
|
|
98
105
|
}
|
|
99
106
|
|
|
100
107
|
async function readIosHierarchy(node, env) {
|
|
@@ -166,7 +173,7 @@ async function readAndroidHierarchy(node, env) {
|
|
|
166
173
|
}
|
|
167
174
|
|
|
168
175
|
async function readAndroidAgentDeviceHierarchy(serial, env) {
|
|
169
|
-
const app =
|
|
176
|
+
const app = nativeAppId(env, 'android');
|
|
170
177
|
const session = nativeSessionName(env, serial, app);
|
|
171
178
|
const stateDir = nativeAgentDeviceStateDir(env, env.METAMASK_RECIPE_PROJECT_ROOT ?? process.cwd(), serial);
|
|
172
179
|
const client = createAgentDeviceClient({
|
|
@@ -257,8 +264,7 @@ function normalizedHierarchy(
|
|
|
257
264
|
const items = nodes.slice(0, VISIBLE_LIMIT);
|
|
258
265
|
const hiddenOrOffscreen = hiddenNodes.slice(0, HIDDEN_LIMIT);
|
|
259
266
|
const name = metadata.screenName ??
|
|
260
|
-
items.find((item) => item.label)?.label
|
|
261
|
-
'MetaMask';
|
|
267
|
+
items.find((item) => item.label)?.label;
|
|
262
268
|
return {
|
|
263
269
|
screen: {
|
|
264
270
|
provider,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Navigate Android Home, Swap, and Perps through native controls and verify visible destinations.
|
|
2
2
|
// Switch Perps Lite or Pro mode through visible controls on Android and iOS.
|
|
3
|
-
import { createAgentDeviceUiTransport } from '@farmslot/
|
|
3
|
+
import { createAgentDeviceUiTransport } from '@farmslot/adapter-rn';
|
|
4
4
|
import { createAgentDeviceClient } from 'agent-device';
|
|
5
5
|
import {
|
|
6
6
|
nativeAgentDeviceStateDir,
|
|
7
|
+
nativeAppId,
|
|
7
8
|
nativeSessionName,
|
|
8
9
|
} from '../platform/native-session-name.mjs';
|
|
9
10
|
import { bridgeCommand } from '../platform/bridge.mjs';
|
|
@@ -51,7 +52,7 @@ export async function navigateOpaqueMobile(input, destination) {
|
|
|
51
52
|
if (!device) {
|
|
52
53
|
throw new Error('Opaque Mobile navigation requires one explicit Android device serial.');
|
|
53
54
|
}
|
|
54
|
-
const app =
|
|
55
|
+
const app = nativeAppId(env, 'android');
|
|
55
56
|
const session = nativeSessionName(env, device, app);
|
|
56
57
|
const stateDir = nativeAgentDeviceStateDir(env, input.context.projectRoot, device);
|
|
57
58
|
const client = createAgentDeviceClient({
|
|
@@ -184,7 +185,7 @@ export async function ensureVisibleAndroidPerpsMode(input, perpsMode) {
|
|
|
184
185
|
'Android Perps mode requires one explicit device serial.',
|
|
185
186
|
);
|
|
186
187
|
}
|
|
187
|
-
const app =
|
|
188
|
+
const app = nativeAppId(env, 'android');
|
|
188
189
|
const session = nativeSessionName(env, device, app);
|
|
189
190
|
const stateDir = nativeAgentDeviceStateDir(env, input.context.projectRoot, device);
|
|
190
191
|
const client = createAgentDeviceClient({
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Drive Android wallet onboarding, lock, unlock, and reset through native accessibility.
|
|
2
2
|
// Wallet observations can navigate home and open the address list to verify the selected account.
|
|
3
|
-
import { createAgentDeviceUiTransport } from '@farmslot/
|
|
3
|
+
import { createAgentDeviceUiTransport } from '@farmslot/adapter-rn';
|
|
4
4
|
import { createAgentDeviceClient } from 'agent-device';
|
|
5
5
|
import {
|
|
6
6
|
nativeAgentDeviceStateDir,
|
|
7
|
+
nativeAppId,
|
|
7
8
|
nativeSessionName,
|
|
8
9
|
} from '../platform/native-session-name.mjs';
|
|
9
10
|
|
|
@@ -249,7 +250,7 @@ function nativeSession(input) {
|
|
|
249
250
|
const env = { ...process.env, ...(input.context?.env ?? {}) };
|
|
250
251
|
const device = String(env.ADB_SERIAL ?? env.ANDROID_SERIAL ?? '').trim();
|
|
251
252
|
if (!device) throw new Error('Opaque Mobile UI execution requires one explicit Android device serial.');
|
|
252
|
-
const app =
|
|
253
|
+
const app = nativeAppId(env, 'android');
|
|
253
254
|
const session = nativeSessionName(env, device, app);
|
|
254
255
|
const stateDir = nativeAgentDeviceStateDir(env, input.context.projectRoot, device);
|
|
255
256
|
const client = createAgentDeviceClient({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Minimal adapter IO for the shared analytics actions.
|
|
2
2
|
//
|
|
3
|
-
// Mirrors the live-adapter contract in
|
|
3
|
+
// Mirrors the live-adapter contract in @farmslot/recipe-cli/harness. Neither
|
|
4
4
|
// existing runAdapter fits: extension's lives under actions/extension/platform
|
|
5
5
|
// and core's carries PerpsController teardown and expect_error handling. A
|
|
6
6
|
// `shared/` action importing either would couple every platform to one of them,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// The one console matcher: classify application console events and apply a
|
|
2
2
|
// recipe-library allowlist of known noise. Used by run diagnostics
|
|
3
|
-
// (src/
|
|
3
|
+
// (src/console-classifier.ts), the assert_no_console_errors action, the
|
|
4
4
|
// allowlist generator, and the recipe library's checks/console-guard.mjs
|
|
5
5
|
// (which imports this file), so every caller judges an event the same way.
|
|
6
6
|
//
|
|
@@ -9,7 +9,8 @@ import { pathToFileURL } from 'node:url';
|
|
|
9
9
|
|
|
10
10
|
import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
11
11
|
|
|
12
|
-
import { recipeRuntimeDir
|
|
12
|
+
import { recipeRuntimeDir } from '@farmslot/recipe-cli/harness';
|
|
13
|
+
import { walletFixturePath } from '../../harness-exports.mjs';
|
|
13
14
|
|
|
14
15
|
export const SIGNER_MODES = Object.freeze(['extension', 'injected']);
|
|
15
16
|
export const DEFAULT_ACCOUNT = 'dev1';
|
|
@@ -649,7 +649,7 @@
|
|
|
649
649
|
},
|
|
650
650
|
"account": {
|
|
651
651
|
"type": "string",
|
|
652
|
-
"description": "
|
|
652
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or 0x address; defaults to dev1. An address outside the fixture is read as given."
|
|
653
653
|
},
|
|
654
654
|
"network": {
|
|
655
655
|
"type": "string",
|
|
@@ -759,7 +759,7 @@
|
|
|
759
759
|
},
|
|
760
760
|
"account": {
|
|
761
761
|
"type": "string",
|
|
762
|
-
"description": "
|
|
762
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or 0x address; defaults to dev1. An address outside the fixture is read as given."
|
|
763
763
|
},
|
|
764
764
|
"network": {
|
|
765
765
|
"type": "string",
|
|
@@ -793,7 +793,7 @@
|
|
|
793
793
|
"properties": {
|
|
794
794
|
"account": {
|
|
795
795
|
"type": "string",
|
|
796
|
-
"description": "
|
|
796
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or 0x address; defaults to dev1. An address outside the fixture is read as given."
|
|
797
797
|
},
|
|
798
798
|
"timeout_ms": {
|
|
799
799
|
"type": "number"
|
|
@@ -818,6 +818,76 @@
|
|
|
818
818
|
],
|
|
819
819
|
"execution_capabilities": []
|
|
820
820
|
},
|
|
821
|
+
"metamask.perps.quote_fees": {
|
|
822
|
+
"description": "core Quote an order's fees through the perps controller's calculateFees (HyperLiquid, testnet by default, read-only): protocol and MetaMask fee rates and amounts (plus the winning fee source on a core that reports it), with an optional rewards discount supplied as RewardsController:getPerpsDiscountForAccount.",
|
|
823
|
+
"schema": {
|
|
824
|
+
"type": "object",
|
|
825
|
+
"properties": {
|
|
826
|
+
"market": {
|
|
827
|
+
"type": "string",
|
|
828
|
+
"description": "Market to quote, e.g. BTC."
|
|
829
|
+
},
|
|
830
|
+
"symbol": {
|
|
831
|
+
"type": "string",
|
|
832
|
+
"description": "Alias for market."
|
|
833
|
+
},
|
|
834
|
+
"order_type": {
|
|
835
|
+
"type": "string",
|
|
836
|
+
"enum": [
|
|
837
|
+
"market",
|
|
838
|
+
"limit"
|
|
839
|
+
],
|
|
840
|
+
"description": "Fee schedule to quote; defaults to market."
|
|
841
|
+
},
|
|
842
|
+
"is_maker": {
|
|
843
|
+
"type": "boolean",
|
|
844
|
+
"description": "Quote maker fees (limit orders that rest)."
|
|
845
|
+
},
|
|
846
|
+
"amount": {
|
|
847
|
+
"type": [
|
|
848
|
+
"string",
|
|
849
|
+
"number"
|
|
850
|
+
],
|
|
851
|
+
"description": "Order notional in USD; adds fee amounts and the blended rate for that size."
|
|
852
|
+
},
|
|
853
|
+
"rewards_discount_bips": {
|
|
854
|
+
"type": "integer",
|
|
855
|
+
"description": "Rewards discount the headless RewardsController answers with, an integer in basis points from 0 through 10000 (6500 = 65%). Omitted: no rewards source, the controller's 'not known yet'."
|
|
856
|
+
},
|
|
857
|
+
"account": {
|
|
858
|
+
"type": "string",
|
|
859
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or 0x address; defaults to dev1. An address outside the fixture is read as given."
|
|
860
|
+
},
|
|
861
|
+
"account_name": {
|
|
862
|
+
"type": "string",
|
|
863
|
+
"description": "Alias for a wallet fixture account name."
|
|
864
|
+
},
|
|
865
|
+
"network": {
|
|
866
|
+
"type": "string",
|
|
867
|
+
"enum": [
|
|
868
|
+
"testnet",
|
|
869
|
+
"mainnet"
|
|
870
|
+
],
|
|
871
|
+
"description": "Venue to quote. Defaults to testnet."
|
|
872
|
+
},
|
|
873
|
+
"timeout_ms": {
|
|
874
|
+
"type": "number"
|
|
875
|
+
}
|
|
876
|
+
},
|
|
877
|
+
"additionalProperties": false
|
|
878
|
+
},
|
|
879
|
+
"examples": [
|
|
880
|
+
{
|
|
881
|
+
"action": "metamask.perps.quote_fees",
|
|
882
|
+
"market": "BTC",
|
|
883
|
+
"amount": "100",
|
|
884
|
+
"rewards_discount_bips": 6500,
|
|
885
|
+
"intent": "Quote a $100 BTC market order with a 65% rewards discount",
|
|
886
|
+
"next": "done"
|
|
887
|
+
}
|
|
888
|
+
],
|
|
889
|
+
"execution_capabilities": []
|
|
890
|
+
},
|
|
821
891
|
"metamask.perps.read_snapshot": {
|
|
822
892
|
"description": "Read global market and account snapshots through the public PerpsController API used by wallet clients.",
|
|
823
893
|
"schema": {
|
|
@@ -835,7 +905,7 @@
|
|
|
835
905
|
},
|
|
836
906
|
"account": {
|
|
837
907
|
"type": "string",
|
|
838
|
-
"description": "Wallet fixture account name or
|
|
908
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or 0x address; defaults to dev1. An address outside the fixture is read as given."
|
|
839
909
|
},
|
|
840
910
|
"account_name": {
|
|
841
911
|
"type": "string",
|
|
@@ -1025,7 +1095,7 @@
|
|
|
1025
1095
|
},
|
|
1026
1096
|
"account": {
|
|
1027
1097
|
"type": "string",
|
|
1028
|
-
"description": "
|
|
1098
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or the 0x address of one; defaults to dev1."
|
|
1029
1099
|
},
|
|
1030
1100
|
"timeout_ms": {
|
|
1031
1101
|
"type": "number"
|
|
@@ -1344,7 +1414,7 @@
|
|
|
1344
1414
|
},
|
|
1345
1415
|
"account": {
|
|
1346
1416
|
"type": "string",
|
|
1347
|
-
"description": "
|
|
1417
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or the 0x address of one; defaults to dev1."
|
|
1348
1418
|
},
|
|
1349
1419
|
"timeout_ms": {
|
|
1350
1420
|
"type": "number"
|
|
@@ -1471,7 +1541,7 @@
|
|
|
1471
1541
|
},
|
|
1472
1542
|
"account": {
|
|
1473
1543
|
"type": "string",
|
|
1474
|
-
"description": "
|
|
1544
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or 0x address; defaults to dev1. An address outside the fixture is read as given."
|
|
1475
1545
|
},
|
|
1476
1546
|
"network": {
|
|
1477
1547
|
"type": "string",
|
|
@@ -1627,7 +1697,7 @@
|
|
|
1627
1697
|
},
|
|
1628
1698
|
"account": {
|
|
1629
1699
|
"type": "string",
|
|
1630
|
-
"description": "
|
|
1700
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or the 0x address of one; defaults to dev1."
|
|
1631
1701
|
},
|
|
1632
1702
|
"timeout_ms": {
|
|
1633
1703
|
"type": "number"
|
|
@@ -1681,7 +1751,7 @@
|
|
|
1681
1751
|
},
|
|
1682
1752
|
"account": {
|
|
1683
1753
|
"type": "string",
|
|
1684
|
-
"description": "Wallet fixture account name
|
|
1754
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or the 0x address of one; defaults to dev1."
|
|
1685
1755
|
},
|
|
1686
1756
|
"market": {
|
|
1687
1757
|
"type": "string",
|
|
@@ -1803,7 +1873,7 @@
|
|
|
1803
1873
|
"properties": {
|
|
1804
1874
|
"account": {
|
|
1805
1875
|
"type": "string",
|
|
1806
|
-
"description": "Wallet fixture account name,
|
|
1876
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or 0x address; defaults to dev1. An address outside the fixture is read as given."
|
|
1807
1877
|
},
|
|
1808
1878
|
"market": {
|
|
1809
1879
|
"type": "string",
|
|
@@ -2010,7 +2080,7 @@
|
|
|
2010
2080
|
"properties": {
|
|
2011
2081
|
"account": {
|
|
2012
2082
|
"type": "string",
|
|
2013
|
-
"description": "Wallet fixture account name
|
|
2083
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or the 0x address of one; defaults to dev1."
|
|
2014
2084
|
},
|
|
2015
2085
|
"market": {
|
|
2016
2086
|
"type": "string",
|
|
@@ -2887,7 +2957,7 @@
|
|
|
2887
2957
|
},
|
|
2888
2958
|
"account": {
|
|
2889
2959
|
"type": "string",
|
|
2890
|
-
"description": "
|
|
2960
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or the 0x address of one; defaults to dev1."
|
|
2891
2961
|
},
|
|
2892
2962
|
"timeout_ms": {
|
|
2893
2963
|
"type": "number"
|
|
@@ -3010,7 +3080,7 @@
|
|
|
3010
3080
|
},
|
|
3011
3081
|
"account": {
|
|
3012
3082
|
"type": "string",
|
|
3013
|
-
"description": "
|
|
3083
|
+
"description": "Wallet fixture account name (dev1, dev2, ...) or the 0x address of one; defaults to dev1."
|
|
3014
3084
|
},
|
|
3015
3085
|
"timeout_ms": {
|
|
3016
3086
|
"type": "number"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deeeed/metamask-harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.80.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mm-harness": "bin/mm-harness"
|
|
@@ -21,17 +21,18 @@
|
|
|
21
21
|
"check:syntax": "find . -name '*.mjs' -print0 | xargs -0 -n1 node --check"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@farmslot/adapter-
|
|
25
|
-
"@farmslot/
|
|
26
|
-
"@farmslot/
|
|
24
|
+
"@farmslot/adapter-rn": "0.17.0",
|
|
25
|
+
"@farmslot/adapter-sdk": "0.3.1",
|
|
26
|
+
"@farmslot/adapter-web": "0.2.0",
|
|
27
|
+
"@farmslot/agent-runtime": "0.17.0",
|
|
27
28
|
"@farmslot/handoff": "^0.3.1",
|
|
28
29
|
"@farmslot/protocol": "0.34.0",
|
|
29
|
-
"@farmslot/recipe-cli": "0.1
|
|
30
|
-
"@farmslot/recipe-
|
|
30
|
+
"@farmslot/recipe-cli": "0.4.1",
|
|
31
|
+
"@farmslot/recipe-runner": "0.24.0",
|
|
31
32
|
"agent-device": "0.19.3",
|
|
32
33
|
"commander": "^12.0.0",
|
|
33
|
-
"es-module-lexer": "2.3.1",
|
|
34
34
|
"esbuild": "0.28.1",
|
|
35
|
+
"tsx": "^4.23.0",
|
|
35
36
|
"viem": "^2.54.3",
|
|
36
37
|
"ws": "8.21.0"
|
|
37
38
|
},
|
|
@@ -47,7 +48,6 @@
|
|
|
47
48
|
"eslint": "^9",
|
|
48
49
|
"globals": "^17.7.0",
|
|
49
50
|
"proper-lockfile": "^4.1.2",
|
|
50
|
-
"tsx": "^4.23.0",
|
|
51
51
|
"typescript": "^5.6.0",
|
|
52
52
|
"typescript-eslint": "^8",
|
|
53
53
|
"vitest": "^4.1.10"
|