@deeeed/metamask-harness 0.79.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 +47 -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/harness-source-fingerprint.mjs +13 -8
- package/adapters/shared/open-debug.mjs +2 -2
- package/adapters/shared/sync-wallet-fixture.sh +8 -5
- package/adapters/terminal/cleanup.mjs +2 -1
- package/adapters/terminal/inject.mjs +2 -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 +2 -2
- package/dist/adapters/core/surface.js +16 -1
- 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 +2 -1
- package/dist/adapters/extension/runtime.js +9 -5
- package/dist/adapters/extension/surface.js +15 -2
- 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 +3 -4
- 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 +8 -7
- package/dist/adapters/mobile/runtime-decision.js +2 -4
- package/dist/adapters/mobile/source-freshness.js +22 -126
- package/dist/adapters/mobile/surface.js +26 -3
- 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/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 +7 -1
- 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 +2 -8
- 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 +4 -9
- 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/doctor.js +2 -3
- 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 +34 -64
- package/dist/performance-observation.js +2 -2
- package/dist/progress.js +1 -1
- package/dist/recipe-assistance-context.js +1 -3
- package/dist/recipe-security.js +2 -59
- package/dist/review/knowledge.js +2 -2
- package/dist/runner.js +5 -3
- package/dist/runtime-context.js +1 -1
- package/dist/task-view.js +2 -3
- package/docs/CONTRIBUTING.md +1 -1
- 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 -9
- 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,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { recipeRuntimeDir } from "
|
|
3
|
+
import { recipeRuntimeDir } from "@farmslot/recipe-cli/harness";
|
|
4
4
|
function readRuntimeContextTarget(target) {
|
|
5
5
|
const file = path.join(target, recipeRuntimeDir(), "agentic-runtime.json");
|
|
6
6
|
let parsed;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import { EXIT, spawnScriptStreaming, shellQuote } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import { execFileSync } from "node:child_process";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { recordDepsBaseline } from "@farmslot/recipe-runner/runtime/deps-readiness";
|
|
4
|
-
import { resolveAndExportMobileToolPaths } from "
|
|
5
|
-
import { EXIT, spawnScriptStreaming } from "../../commands/shared.js";
|
|
6
|
-
import { shellQuote } from "../../commands/parse-args.js";
|
|
5
|
+
import { resolveAndExportMobileToolPaths } from "@farmslot/adapter-rn";
|
|
7
6
|
import { runnerDir } from "../../paths.js";
|
|
8
7
|
import {
|
|
9
8
|
decideMobileReadiness,
|
|
@@ -401,7 +400,7 @@ async function dispatchAction(action, target, platform, json, preflightMode = "f
|
|
|
401
400
|
leaf,
|
|
402
401
|
withWatcherPort(["--target", cwd, ...extra], watcherPort),
|
|
403
402
|
target,
|
|
404
|
-
{
|
|
403
|
+
{ RECIPE_RN_METRO_ENV_FINGERPRINT: metroEnvFingerprint ?? mobileMetroEnvCheck(path.resolve(target)).fingerprint }
|
|
405
404
|
);
|
|
406
405
|
}
|
|
407
406
|
case "start-console-forwarder": {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { recipeRuntimeDir } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import { execFileSync } from "node:child_process";
|
|
2
3
|
import crypto from "node:crypto";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
import os from "node:os";
|
|
5
6
|
import path from "node:path";
|
|
6
|
-
import { recipeRuntimeDir } from "../../paths.js";
|
|
7
7
|
import { resolveSlotPortsByRepo } from "../../../adapters/shared/resolve-slot-ports-core.mjs";
|
|
8
8
|
const RUNWAY_IOS_METADATA = {
|
|
9
9
|
artifactName: "ios-app-main-dev-expo",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { optionFlag, optionString, parsePort } from "
|
|
1
|
+
import { optionFlag, optionString, parsePort } from "@farmslot/recipe-cli/harness";
|
|
2
2
|
import { detectOrphanMetros, mobileToolDoctorChecks } from "./doctor-checks.js";
|
|
3
3
|
import { ensureMobilePerpsEnvironment, mobilePerpsEnvironment } from "./perps-env.js";
|
|
4
4
|
const mobileReadiness = {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function resolveAndroidDeviceSerial(env = process.env) {
|
|
2
|
+
return env.ADB_SERIAL?.trim() || process.env.ADB_SERIAL?.trim() || void 0;
|
|
3
|
+
}
|
|
4
|
+
function resolveMobileIosSimulatorName(env = process.env) {
|
|
5
|
+
const explicit = env.IOS_SIMULATOR?.trim() || env.SIM_UDID?.trim();
|
|
6
|
+
if (explicit) return explicit;
|
|
7
|
+
const slot = env.FARMSLOT_SLOT_ID?.trim() || env.SLOT_ID?.trim();
|
|
8
|
+
if (!slot) return void 0;
|
|
9
|
+
const suffix = slot.includes("-") ? slot.slice(slot.lastIndexOf("-") + 1) : slot;
|
|
10
|
+
return suffix || void 0;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
resolveAndroidDeviceSerial,
|
|
14
|
+
resolveMobileIosSimulatorName
|
|
15
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { recipeRuntimePath } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import { randomBytes } from "node:crypto";
|
|
2
3
|
import fs from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
|
-
import { recipeRuntimePath } from "../../paths.js";
|
|
5
5
|
import {
|
|
6
6
|
assertAndroidReleaseArtifactRuntime
|
|
7
7
|
} from "./release-artifact.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { EXIT, spawnScript } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import path from "node:path";
|
|
2
|
-
import { EXIT, spawnScript } from "../../commands/shared.js";
|
|
3
3
|
import { runnerDir } from "../../paths.js";
|
|
4
4
|
function reloadMobile(target, json) {
|
|
5
5
|
const script = path.join(runnerDir, "adapters/mobile/reload-app.mjs");
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import { isRecord } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import { spawnSync } from "node:child_process";
|
|
2
3
|
import path from "node:path";
|
|
3
|
-
import {
|
|
4
|
+
import { IOS_SIMULATOR_RECORDING_TARGET_PREFIX } from "@farmslot/adapter-rn";
|
|
4
5
|
import { runnerDir } from "../../paths.js";
|
|
5
6
|
import { devicePlatformFromEnv } from "../performance/device-platform.js";
|
|
6
7
|
import {
|
|
7
|
-
IOS_SIMULATOR_RECORDING_TARGET_PREFIX,
|
|
8
8
|
resolveAndroidDeviceSerial,
|
|
9
9
|
resolveMobileIosSimulatorName
|
|
10
|
-
} from "
|
|
10
|
+
} from "./recording-target.js";
|
|
11
|
+
import { mobileAppIdentityEnv } from "./app-identity.js";
|
|
11
12
|
import { requireCurrentMobileReleaseArtifactState } from "./release-artifact-state.js";
|
|
12
13
|
const EXPLICIT_DEVICE_KEYS = [
|
|
13
14
|
"PLATFORM",
|
|
14
|
-
"
|
|
15
|
+
"RECIPE_RN_EXPLICIT_PLATFORM",
|
|
15
16
|
"IOS_SIMULATOR",
|
|
16
17
|
"SIM_UDID",
|
|
17
18
|
"ADB_SERIAL",
|
|
@@ -21,7 +22,7 @@ const EXPLICIT_DEVICE_KEYS = [
|
|
|
21
22
|
];
|
|
22
23
|
const mobileRun = {
|
|
23
24
|
pinnedEnv() {
|
|
24
|
-
if (!process.env.
|
|
25
|
+
if (!process.env.RECIPE_RN_EXPLICIT_PLATFORM) return void 0;
|
|
25
26
|
return Object.fromEntries(EXPLICIT_DEVICE_KEYS.map((key) => [key, process.env[key]]));
|
|
26
27
|
},
|
|
27
28
|
envKeys: ["METAMASK_RECIPE_MOBILE_OPAQUE_RUNTIME", "ANDROID_PACKAGE_ID", "ADB_SERIAL", "ANDROID_SERIAL"],
|
|
@@ -49,7 +50,7 @@ const mobileRun = {
|
|
|
49
50
|
ANDROID_TARGET_DEVICE_NAME: process.env.ANDROID_TARGET_DEVICE_NAME,
|
|
50
51
|
ADB_SERIAL: process.env.ADB_SERIAL,
|
|
51
52
|
ANDROID_SERIAL: process.env.ANDROID_SERIAL,
|
|
52
|
-
|
|
53
|
+
...mobileAppIdentityEnv(),
|
|
53
54
|
METAMASK_RECIPE_MOBILE_OPAQUE_RUNTIME: process.env.METAMASK_RECIPE_MOBILE_OPAQUE_RUNTIME
|
|
54
55
|
}),
|
|
55
56
|
// An installed release artifact is opaque: no harness HUD inside it.
|
|
@@ -78,7 +79,7 @@ const mobileRecording = {
|
|
|
78
79
|
const androidSerial = resolveAndroidDeviceSerial();
|
|
79
80
|
const iosSimulator = androidSerial ? void 0 : resolveMobileIosSimulatorName();
|
|
80
81
|
if (!androidSerial && !iosSimulator) return void 0;
|
|
81
|
-
const { createAndroidVideoRecorder, createIosSimulatorVideoRecorder } = await import("
|
|
82
|
+
const { createAndroidVideoRecorder, createIosSimulatorVideoRecorder } = await import("@farmslot/adapter-rn");
|
|
82
83
|
if (androidSerial) {
|
|
83
84
|
const { createAndroidMirrorVideoRecorder } = await import("@farmslot/recipe-runner");
|
|
84
85
|
return createAndroidMirrorVideoRecorder({ serial: androidSerial, fallback: createAndroidVideoRecorder(androidSerial) });
|
|
@@ -11,10 +11,8 @@ import {
|
|
|
11
11
|
supersededErrorCapture
|
|
12
12
|
} from "@farmslot/recipe-runner/runtime/log-analysis";
|
|
13
13
|
import { probeMetroPackager } from "@farmslot/recipe-runner/runtime/metro-probe";
|
|
14
|
-
import { color } from "
|
|
15
|
-
import {
|
|
16
|
-
import { recipeRuntimePath } from "../../paths.js";
|
|
17
|
-
import { resolveMobileToolPath } from "../../../library/actions/mobile/platform/tool-paths.mjs";
|
|
14
|
+
import { color, recipeRuntimePath, shellQuote } from "@farmslot/recipe-cli/harness";
|
|
15
|
+
import { resolveMobileToolPath } from "@farmslot/adapter-rn";
|
|
18
16
|
import { mobileProductMarkers } from "./deps-markers.js";
|
|
19
17
|
import { mobileMetroEnvCheck } from "./metro-env.js";
|
|
20
18
|
const BUNDLE_ERR = /Bundling failed|Unable to resolve /u;
|
|
@@ -1,135 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
const ENV_INPUTS = [".js.env", ".env", ".env.local"];
|
|
1
|
+
import { recordSourceBaseline, sourceCheck, sourceFingerprint } from "@farmslot/adapter-rn";
|
|
2
|
+
import { recipeRuntimePath } from "@farmslot/recipe-cli/harness";
|
|
3
|
+
const MOBILE_SOURCE_INPUTS = {
|
|
4
|
+
paths: [
|
|
5
|
+
"app",
|
|
6
|
+
"locales",
|
|
7
|
+
"index.js",
|
|
8
|
+
"shim.js",
|
|
9
|
+
"shimPerf.js",
|
|
10
|
+
"ReactotronConfig.js",
|
|
11
|
+
"wdyr.js",
|
|
12
|
+
"app.config.js",
|
|
13
|
+
"babel.config.js",
|
|
14
|
+
"metro.config.js",
|
|
15
|
+
"metro.transform.js",
|
|
16
|
+
"package.json"
|
|
17
|
+
],
|
|
18
|
+
envFiles: [".js.env", ".env", ".env.local"]
|
|
19
|
+
};
|
|
21
20
|
const BASELINE_FILE = "mobile-source-baseline.json";
|
|
22
21
|
function mobileSourceFingerprint(target) {
|
|
23
|
-
|
|
24
|
-
const head = tryGit(target, ["rev-parse", "HEAD"]);
|
|
25
|
-
if (head === null) {
|
|
26
|
-
hash.update("non-git\0");
|
|
27
|
-
for (const relative of SOURCE_PATHS) {
|
|
28
|
-
hashPath(hash, target, relative);
|
|
29
|
-
}
|
|
30
|
-
} else {
|
|
31
|
-
hash.update(head);
|
|
32
|
-
hash.update(git(target, ["diff", "--no-ext-diff", "--binary", "HEAD", "--", ...SOURCE_PATHS]));
|
|
33
|
-
const untracked = git(target, [
|
|
34
|
-
"ls-files",
|
|
35
|
-
"--others",
|
|
36
|
-
"--exclude-standard",
|
|
37
|
-
"-z",
|
|
38
|
-
"--",
|
|
39
|
-
...SOURCE_PATHS
|
|
40
|
-
]).toString("utf8").split("\0").filter(Boolean).sort();
|
|
41
|
-
for (const relative of untracked) {
|
|
42
|
-
hash.update(`untracked\0${relative}\0`);
|
|
43
|
-
hash.update(fs.readFileSync(path.join(target, relative)));
|
|
44
|
-
hash.update("\0");
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
for (const relative of ENV_INPUTS) {
|
|
48
|
-
const absolute = path.join(target, relative);
|
|
49
|
-
hash.update(`env\0${relative}\0`);
|
|
50
|
-
hash.update(fs.existsSync(absolute) ? fs.readFileSync(absolute) : "<absent>");
|
|
51
|
-
hash.update("\0");
|
|
52
|
-
}
|
|
53
|
-
return hash.digest("hex");
|
|
22
|
+
return sourceFingerprint(target, MOBILE_SOURCE_INPUTS);
|
|
54
23
|
}
|
|
55
24
|
function mobileSourceCheck(target) {
|
|
56
|
-
|
|
57
|
-
const baseline = readBaseline(target);
|
|
58
|
-
return {
|
|
59
|
-
fingerprint,
|
|
60
|
-
status: baseline === null ? "missing" : baseline.fingerprint === fingerprint ? "current" : "changed"
|
|
61
|
-
};
|
|
25
|
+
return sourceCheck(target, MOBILE_SOURCE_INPUTS, recipeRuntimePath(target, BASELINE_FILE));
|
|
62
26
|
}
|
|
63
27
|
function recordMobileSourceBaseline(target, expectedFingerprint) {
|
|
64
|
-
|
|
65
|
-
const marker = recipeRuntimePath(target, BASELINE_FILE);
|
|
66
|
-
const temporary = `${marker}.${process.pid}.${Date.now()}.tmp`;
|
|
67
|
-
const baseline = {
|
|
68
|
-
schemaVersion: 1,
|
|
69
|
-
fingerprint: expectedFingerprint,
|
|
70
|
-
recordedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
71
|
-
};
|
|
72
|
-
fs.mkdirSync(path.dirname(marker), { recursive: true });
|
|
73
|
-
try {
|
|
74
|
-
fs.writeFileSync(temporary, `${JSON.stringify(baseline, null, 2)}
|
|
75
|
-
`, { mode: 384 });
|
|
76
|
-
if (mobileSourceFingerprint(target) !== expectedFingerprint) return false;
|
|
77
|
-
fs.renameSync(temporary, marker);
|
|
78
|
-
if (mobileSourceFingerprint(target) !== expectedFingerprint) {
|
|
79
|
-
if (readBaseline(target)?.fingerprint === expectedFingerprint) fs.rmSync(marker, { force: true });
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
} finally {
|
|
83
|
-
fs.rmSync(temporary, { force: true });
|
|
84
|
-
}
|
|
85
|
-
return true;
|
|
86
|
-
}
|
|
87
|
-
function git(target, args) {
|
|
88
|
-
return execFileSync("git", args, {
|
|
89
|
-
cwd: target,
|
|
90
|
-
encoding: "buffer",
|
|
91
|
-
maxBuffer: 128 * 1024 * 1024,
|
|
92
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
function tryGit(target, args) {
|
|
96
|
-
try {
|
|
97
|
-
return git(target, args);
|
|
98
|
-
} catch {
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
function hashPath(hash, root, relative) {
|
|
103
|
-
const absolute = path.join(root, relative);
|
|
104
|
-
if (!fs.existsSync(absolute)) {
|
|
105
|
-
hash.update(`absent\0${relative}\0`);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const stat = fs.lstatSync(absolute);
|
|
109
|
-
if (stat.isDirectory()) {
|
|
110
|
-
hash.update(`directory\0${relative}\0`);
|
|
111
|
-
for (const child of fs.readdirSync(absolute).sort()) {
|
|
112
|
-
hashPath(hash, root, path.join(relative, child));
|
|
113
|
-
}
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
if (stat.isSymbolicLink()) {
|
|
117
|
-
hash.update(`symlink\0${relative}\0${fs.readlinkSync(absolute)}\0`);
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
hash.update(`file\0${relative}\0`);
|
|
121
|
-
hash.update(fs.readFileSync(absolute));
|
|
122
|
-
hash.update("\0");
|
|
123
|
-
}
|
|
124
|
-
function readBaseline(target) {
|
|
125
|
-
try {
|
|
126
|
-
const parsed = JSON.parse(
|
|
127
|
-
fs.readFileSync(recipeRuntimePath(target, BASELINE_FILE), "utf8")
|
|
128
|
-
);
|
|
129
|
-
return parsed.schemaVersion === 1 && typeof parsed.fingerprint === "string" ? parsed : null;
|
|
130
|
-
} catch {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
28
|
+
return recordSourceBaseline(target, MOBILE_SOURCE_INPUTS, recipeRuntimePath(target, BASELINE_FILE), expectedFingerprint);
|
|
133
29
|
}
|
|
134
30
|
export {
|
|
135
31
|
mobileSourceCheck,
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
+
import { recipeRuntimePath, shellQuote, writeInteractiveProgress } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import { spawnSync } from "node:child_process";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { defineAdapter } from "@farmslot/adapter-sdk";
|
|
4
|
-
import {
|
|
5
|
-
import { shellQuote } from "../../commands/parse-args.js";
|
|
5
|
+
import { runnerDir } from "../../paths.js";
|
|
6
6
|
import { resolveMobileSlotPorts } from "../slot-ports.js";
|
|
7
7
|
import { mobileRuntimeStatus } from "./prepare.js";
|
|
8
8
|
import { hasRunwayProvisionBaseline, provisionRunwayMobile } from "./provision.js";
|
|
9
9
|
import { adapterRegistry } from "../registry.js";
|
|
10
|
-
import { writeInteractiveProgress } from "../../commands/shared.js";
|
|
11
10
|
import { mobileActions } from "./actions.js";
|
|
12
11
|
import { mobileHarness, mobilePrepare, mobileRuntimeContext } from "./overlay.js";
|
|
13
12
|
import { mobileReadiness, mobileRuntimeDecision } from "./readiness.js";
|
|
14
13
|
import { clearMobileReleaseArtifactState } from "./release-artifact-state.js";
|
|
15
14
|
import { mobileDiagnostics, mobileObservation, mobileRecording, mobileRun } from "./run.js";
|
|
16
15
|
import { mobileSourceFingerprint } from "./source-freshness.js";
|
|
16
|
+
import { checkoutHas, checkoutHasDir } from "../checkout-files.js";
|
|
17
17
|
function mobileRuntimeNextAction(reasonCode, target, platform) {
|
|
18
18
|
const resolved = shellQuote(path.resolve(target));
|
|
19
19
|
return reasonCode === "deps-missing" || reasonCode === "deps-partial" || reasonCode === "deps-stale" ? `cd ${resolved} && yarn setup` : `mm-harness launch ${platform} --adapter mobile --target ${resolved}`;
|
|
@@ -53,6 +53,9 @@ const mobileSurface = defineAdapter({
|
|
|
53
53
|
devServer: {
|
|
54
54
|
label: "metro",
|
|
55
55
|
describe: () => "Metro dev server",
|
|
56
|
+
// Metro's leaves read the port as METRO_PORT; run and call take it as --metro-port.
|
|
57
|
+
portEnv: ["METRO_PORT"],
|
|
58
|
+
portFlags: ["metroPort"],
|
|
56
59
|
stop(target) {
|
|
57
60
|
const leaf = path.join(runnerDir, "adapters", "mobile", "stop-metro.sh");
|
|
58
61
|
const args = ["--target", target];
|
|
@@ -70,6 +73,26 @@ const mobileSurface = defineAdapter({
|
|
|
70
73
|
appLogSource(target) {
|
|
71
74
|
return { label: "app", path: recipeRuntimePath(target, "app-console.log") };
|
|
72
75
|
},
|
|
76
|
+
detect: {
|
|
77
|
+
remote: (url) => url.includes("metamask-mobile"),
|
|
78
|
+
files: (target) => checkoutHas(target, "scripts/skills-sync.mts") || checkoutHasDir(target, "ios") && checkoutHasDir(target, "android") && checkoutHasDir(target, "app/core")
|
|
79
|
+
},
|
|
80
|
+
// `launch ios|android`, and --platform ios|android, select Mobile.
|
|
81
|
+
targets: ["ios", "android"],
|
|
82
|
+
flags: {
|
|
83
|
+
launch: ["build", "watch", "verify", "runway", "clearMetro"],
|
|
84
|
+
commands: ["clearMetro", "resolveOnly"]
|
|
85
|
+
},
|
|
86
|
+
failurePatterns: {
|
|
87
|
+
captureProtected: {
|
|
88
|
+
pattern: /SCREENSHOT_PROTECTED|screenshot is protected by FLAG_SECURE/iu,
|
|
89
|
+
message: "the focused Android window intentionally blocks screenshots; a black capture cannot be used as evidence.",
|
|
90
|
+
userAction: "unlock or navigate to a non-protected screen, then rerun the screenshot action"
|
|
91
|
+
},
|
|
92
|
+
transportFirst: /CDP_TIMEOUT|Mobile CDP bridge command timed out|NO_TARGET|WS_CLOSED/iu,
|
|
93
|
+
walletState: /fixture|keyring|not seeded|\bsrp\b|password|onboard/iu,
|
|
94
|
+
transport: /metro|bridge|bundle|packager|dev client/iu
|
|
95
|
+
},
|
|
73
96
|
hints: {
|
|
74
97
|
launch: "mm-harness launch ios",
|
|
75
98
|
relaunch: "mm-harness launch ios",
|
|
@@ -3,9 +3,13 @@ import { promisify } from "node:util";
|
|
|
3
3
|
import { bridgeCommand, evalAsync, evalSync, MOBILE_BRIDGE_ERROR_CODES, selectBridgeStatusEntry, simulatorScreenshot } from "../../../library/actions/mobile/platform/bridge.mjs";
|
|
4
4
|
import { observeNativeUi } from "../../../library/actions/mobile/platform/observe-ui.mjs";
|
|
5
5
|
import { nativeAgentDeviceStateDir } from "../../../library/actions/mobile/platform/native-session-name.mjs";
|
|
6
|
-
import { resolveMobileToolPath } from "
|
|
6
|
+
import { resolveMobileToolPath } from "@farmslot/adapter-rn";
|
|
7
7
|
import { isRecord, traceText } from "../../action-values.js";
|
|
8
|
-
import { runLiveAdapterScript } from "
|
|
8
|
+
import { runLiveAdapterScript } from "@farmslot/recipe-cli/harness";
|
|
9
|
+
import { trustedMutationContextExtras } from "../../funding-execution-context.js";
|
|
10
|
+
import { LIBRARY_ACTION_NAMESPACE } from "../../paths.js";
|
|
11
|
+
import { liveTsxCandidates } from "../../live-tsx.js";
|
|
12
|
+
import { mobileAppIdentityEnv } from "./app-identity.js";
|
|
9
13
|
const execFileAsync = promisify(execFile);
|
|
10
14
|
function sleep(ms) {
|
|
11
15
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -213,7 +217,10 @@ async function sendMobileBridgeCommand(command, context) {
|
|
|
213
217
|
if (!handler) {
|
|
214
218
|
throw new Error(`React Native bridge command ${command.command} is not implemented by the MetaMask runner transport.`);
|
|
215
219
|
}
|
|
216
|
-
return handler(command.payload,
|
|
220
|
+
return handler(command.payload, {
|
|
221
|
+
...context,
|
|
222
|
+
env: { ...context.env, ...mobileAppIdentityEnv(context.env) }
|
|
223
|
+
});
|
|
217
224
|
}
|
|
218
225
|
function mobileUiInput(context, command, payload) {
|
|
219
226
|
return uiInputFor(context, { action: `ui.${command}`, node: payload });
|
|
@@ -235,8 +242,11 @@ async function handleMobileNavigate(payload, context) {
|
|
|
235
242
|
const live = await runLiveAdapterScript({
|
|
236
243
|
platform: "mobile",
|
|
237
244
|
action: "ui.navigate",
|
|
245
|
+
namespace: LIBRARY_ACTION_NAMESPACE,
|
|
238
246
|
node: payload,
|
|
239
|
-
context
|
|
247
|
+
context,
|
|
248
|
+
contextExtras: trustedMutationContextExtras(context),
|
|
249
|
+
tsxCandidates: liveTsxCandidates()
|
|
240
250
|
});
|
|
241
251
|
if (!live) throw new Error("ui.navigate requires library/actions/mobile/ui/navigate.mjs.");
|
|
242
252
|
return isRecord(live.result) ? { ...live.result, liveAdapter: live.script } : live.result;
|
|
@@ -586,7 +596,8 @@ async function executeNativeProviderAction(action, node, context, createTranspor
|
|
|
586
596
|
if (platform === "android" && action === "ui.swipe" && isCoordinateTarget(node.target)) {
|
|
587
597
|
return executeAndroidCoordinateSwipe(node, String(device));
|
|
588
598
|
}
|
|
589
|
-
const
|
|
599
|
+
const identity = mobileAppIdentityEnv(context.env);
|
|
600
|
+
const app = platform === "android" ? identity.ANDROID_PACKAGE_ID : identity.IOS_BUNDLE_ID;
|
|
590
601
|
const session = (platform === "ios" ? `mm-harness-${process.pid}-${device}` : `mm-harness-${process.pid}-${context.nodeId}`).replace(/[^a-zA-Z0-9._-]/gu, "-");
|
|
591
602
|
const stateDir = nativeAgentDeviceStateDir(context.env ?? {}, context.projectRoot, String(device));
|
|
592
603
|
let transport;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
+
import { recipeHarnessPath, recipeHarnessRoot, recipeRuntimeDir, spawnScriptStreaming, readRuntimeContextField } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import { execFileSync } from "node:child_process";
|
|
2
3
|
import crypto from "node:crypto";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
import path from "node:path";
|
|
5
|
-
import {
|
|
6
|
-
import { readRuntimeContextField } from "../../harness.js";
|
|
7
|
-
import { recipeHarnessPath, recipeHarnessRoot, recipeRuntimeDir, runnerDir } from "../../paths.js";
|
|
6
|
+
import { runnerDir } from "../../paths.js";
|
|
8
7
|
const USAGE = "Usage: mm-harness verify --adapter mobile -- [--target <metamask-mobile>] [--artifacts-dir <dir>] [--static-only] [--platform ios|android] [--preflight-mode fast|auto|default|rebuild-native|clean] [--no-auto-start]";
|
|
9
8
|
const ENV_FILES = [".js.env", ".env", ".env.local"];
|
|
10
9
|
const PREFLIGHT_MODES = ["fast", "auto", "default", "rebuild-native", "clean"];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
function devicePlatformFromEnv(env) {
|
|
2
2
|
const explicit = String(
|
|
3
|
-
env.
|
|
3
|
+
env.RECIPE_RN_EXPLICIT_PLATFORM ?? env.RECIPE_HARNESS_PLATFORM ?? ""
|
|
4
4
|
).toLowerCase();
|
|
5
5
|
if (explicit === "android" || explicit === "ios") return explicit;
|
|
6
6
|
return env.ADB_SERIAL || env.ANDROID_SERIAL || env.ANDROID_DEVICE ? "android" : "ios";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { recipeRuntimeDir } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import { execFileSync } from "node:child_process";
|
|
2
3
|
import fs from "node:fs";
|
|
3
4
|
import os from "node:os";
|
|
4
5
|
import path from "node:path";
|
|
5
|
-
import { recipeRuntimeDir } from "../paths.js";
|
|
6
6
|
import {
|
|
7
7
|
formatExtensionIdentityPorts,
|
|
8
8
|
resolveDefaultExtensionPorts,
|
package/dist/adapters/surface.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { recipeRuntimePath } from "@farmslot/recipe-cli/harness";
|
|
3
4
|
import { verifyCapture } from "../../../library/actions/shared/console-collector.mjs";
|
|
4
|
-
import { recipeRuntimePath } from "../../paths.js";
|
|
5
5
|
import { ensureConsoleCollector } from "../console-capture.js";
|
|
6
6
|
const TERMINAL_CONSOLE_FILES = Object.freeze({
|
|
7
7
|
app: "app-console.log",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { flag, str } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import { execFileSync } from "node:child_process";
|
|
2
3
|
import path from "node:path";
|
|
3
|
-
import { flag, str } from "../../commands/shared.js";
|
|
4
4
|
import { runnerDir } from "../../paths.js";
|
|
5
5
|
const TERMINAL_ONLY_LAUNCH_OPTIONS = Object.freeze({
|
|
6
6
|
signer: "--signer",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isRecord } from "@farmslot/recipe-cli/harness";
|
|
2
|
+
import { verifyOwnedCollectorControl } from "../console-capture.js";
|
|
1
3
|
import { devicePlatformFromEnv } from "../performance/device-platform.js";
|
|
2
4
|
import {
|
|
3
5
|
ensureTerminalConsoleCapture,
|
|
@@ -11,10 +13,31 @@ const terminalDiagnostics = {
|
|
|
11
13
|
start: (projectRoot) => ensureTerminalConsoleCapture(projectRoot),
|
|
12
14
|
files: (projectRoot) => terminalCaptureFiles(projectRoot),
|
|
13
15
|
cdpPort: () => terminalCdpPort(),
|
|
14
|
-
verifyControl: (capture) => verifyTerminalConsoleControl(capture)
|
|
16
|
+
verifyControl: (capture) => verifyOwnedCollectorControl(capture, () => verifyTerminalConsoleControl(capture))
|
|
15
17
|
},
|
|
16
|
-
|
|
18
|
+
requestLog: {
|
|
19
|
+
path: (projectRoot) => terminalRuntimeFile(projectRoot, "wallet-requests.jsonl"),
|
|
20
|
+
findings: (lines) => walletRequestFindings(lines)
|
|
21
|
+
}
|
|
17
22
|
};
|
|
23
|
+
function walletRequestFindings(lines) {
|
|
24
|
+
const findings = [];
|
|
25
|
+
for (const line of lines) {
|
|
26
|
+
let entry;
|
|
27
|
+
try {
|
|
28
|
+
entry = JSON.parse(line);
|
|
29
|
+
} catch {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (!isRecord(entry)) continue;
|
|
33
|
+
let text = null;
|
|
34
|
+
if (entry.kind === "blocked-mainnet" && entry.probe !== true) text = `blocked-mainnet: ${String(entry.transport ?? "request")} to ${String(entry.url ?? "?")}`;
|
|
35
|
+
else if (entry.kind === "refused-mainnet") text = `refused-mainnet: ${String(entry.method ?? "?")} (${String(entry.reason ?? "?")})`;
|
|
36
|
+
else if (entry.kind === "unattributed") text = `unattributed wallet ${entry.binding === "request" ? "request" : "log entry"}${typeof entry.method === "string" ? ` (${entry.method})` : ""}`;
|
|
37
|
+
if (text) findings.push({ level: "error", source: "wallet", text });
|
|
38
|
+
}
|
|
39
|
+
return findings;
|
|
40
|
+
}
|
|
18
41
|
const terminalObservation = {
|
|
19
42
|
network: {
|
|
20
43
|
backend: async (_target, env, artifactsDir) => (await import("../../network-observation.js")).createExtensionNetworkBackend(env, artifactsDir)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { shellQuote } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import path from "node:path";
|
|
2
3
|
import { defineAdapter } from "@farmslot/adapter-sdk";
|
|
3
|
-
import { shellQuote } from "../../commands/parse-args.js";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import { TERMINAL_CONSOLE_FILES, terminalRuntimeFile } from "./console-capture.js";
|
|
6
6
|
import { stopTerminalBrowserSync } from "./stop.js";
|
|
@@ -9,6 +9,7 @@ import { terminalActions } from "./actions.js";
|
|
|
9
9
|
import { terminalHarness, terminalRuntimeContext } from "./overlay.js";
|
|
10
10
|
import { terminalReadiness } from "./readiness.js";
|
|
11
11
|
import { terminalDiagnostics, terminalObservation } from "./run.js";
|
|
12
|
+
import { checkoutHas, checkoutHasDir } from "../checkout-files.js";
|
|
12
13
|
function portFromEnv(...names) {
|
|
13
14
|
for (const name of names) {
|
|
14
15
|
const raw = process.env[name];
|
|
@@ -98,6 +99,11 @@ const terminalSurface = defineAdapter({
|
|
|
98
99
|
appLogSource(target) {
|
|
99
100
|
return { label: "app-console", path: terminalRuntimeFile(target, TERMINAL_CONSOLE_FILES.app) };
|
|
100
101
|
},
|
|
102
|
+
detect: {
|
|
103
|
+
remote: (url) => url.includes("va-mmcx-terminal"),
|
|
104
|
+
files: (target) => checkoutHasDir(target, "src/features/perpetuals") && ["next.config.ts", "next.config.mjs", "next.config.js"].some((file) => checkoutHas(target, file))
|
|
105
|
+
},
|
|
106
|
+
flags: { launch: ["freshProfile", "headless", "headful"] },
|
|
101
107
|
hints: {
|
|
102
108
|
launch: "mm-harness launch --adapter terminal --cdp-port <port> --watcher-port <app port>",
|
|
103
109
|
relaunch: "mm-harness launch --adapter terminal --fresh-profile",
|
package/dist/adapters.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import http from "node:http";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { compatibilityMode, fixtureSummary, repoShape } from "./doctor.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
} from "./
|
|
4
|
+
import { runLiveAdapterScript } from "@farmslot/recipe-cli/harness";
|
|
5
|
+
import { trustedMutationContextExtras } from "./funding-execution-context.js";
|
|
6
|
+
import { LIBRARY_ACTION_NAMESPACE } from "./paths.js";
|
|
7
|
+
import { liveTsxCandidates } from "./live-tsx.js";
|
|
7
8
|
import { resolveWalletImportCredentials, validateWalletImportOptions } from "../library/actions/shared/wallet/import-source.mjs";
|
|
8
9
|
import { isRecord, traceText } from "./action-values.js";
|
|
9
10
|
import { getAdapterSurface } from "./adapters/surface.js";
|
|
@@ -109,9 +110,12 @@ async function runLiveFirst(platform, action, node, context, forceLive = false,
|
|
|
109
110
|
const live = await runLiveAdapterScript({
|
|
110
111
|
platform,
|
|
111
112
|
action,
|
|
113
|
+
namespace: LIBRARY_ACTION_NAMESPACE,
|
|
112
114
|
node,
|
|
113
115
|
context,
|
|
114
|
-
prepared: preparedLiveAdapters?.get(action)
|
|
116
|
+
prepared: preparedLiveAdapters?.get(action),
|
|
117
|
+
contextExtras: trustedMutationContextExtras(context),
|
|
118
|
+
tsxCandidates: liveTsxCandidates()
|
|
115
119
|
});
|
|
116
120
|
if (!live) return null;
|
|
117
121
|
const liveResult = isRecord(live.result) ? live.result : { result: live.result };
|
package/dist/advisor-policy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { optionString, usageError } from "@farmslot/recipe-cli/harness";
|
|
1
2
|
import { assessmentProvider } from "./assessment-providers.js";
|
|
2
|
-
import { optionString, usageError } from "./commands/parse-args.js";
|
|
3
3
|
import { configPath, parseAdvisorSettings, readConfig } from "./review/knowledge.js";
|
|
4
4
|
function resolveAdvisorPolicy(options, env = process.env, config) {
|
|
5
5
|
const saved = (config ?? readConfig(configPath(env))).advisor ?? {};
|
package/dist/checkout-view.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { color } from "
|
|
3
|
+
import { color, recipeRuntimeDir } from "@farmslot/recipe-cli/harness";
|
|
4
4
|
import { renderRuntimeContext, runtimeContextSummary } from "./doctor.js";
|
|
5
|
-
import { recipeRuntimeDir } from "./paths.js";
|
|
6
5
|
import {
|
|
7
6
|
configPath,
|
|
8
7
|
declaredLibraryPathEnv,
|