@deeeed/metamask-harness 0.79.0 → 0.81.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 +73 -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 +16 -64
- 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/adapters/terminal/launch.mjs +17 -13
- package/adapters/terminal/lib/mainnet-guard.mjs +9 -0
- package/adapters/terminal/lib/readiness.mjs +20 -12
- package/adapters/terminal/policy.mjs +35 -0
- package/adapters/terminal/verify.mjs +10 -3
- package/adapters/terminal/wallet-host.mjs +43 -225
- 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 +8 -4
- 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/actions.js +6 -2
- 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 +14 -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 +135 -14
- 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/actions.js +4 -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/network-observer.js +68 -0
- package/dist/adapters/mobile/performance-observer.js +2 -4
- 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 +39 -15
- 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/perps-order-inputs.js +36 -0
- package/dist/adapters/proof-failure.js +11 -0
- package/dist/adapters/slot-ports.js +1 -1
- package/dist/adapters/surface.js +1 -0
- package/dist/adapters/terminal/actions.js +4 -1
- package/dist/adapters/terminal/console-capture.js +1 -1
- package/dist/adapters/terminal/doctor-checks.js +2 -0
- package/dist/adapters/terminal/launch.js +4 -1
- package/dist/adapters/terminal/overlay.js +8 -1
- package/dist/adapters/terminal/run.js +33 -5
- package/dist/adapters/terminal/surface.js +9 -1
- package/dist/adapters.js +27 -7
- package/dist/advisor-policy.js +1 -1
- package/dist/checkout-view.js +1 -2
- package/dist/cli.js +59 -21
- package/dist/command-contract.js +1 -26
- package/dist/commands/check.js +33 -10
- package/dist/commands/checklist.js +1 -1
- package/dist/commands/completion-candidates.js +6 -14
- 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/logs.js +3 -3
- 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/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 +5 -8
- 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/engine.js +57 -0
- package/dist/funding-execution-context.js +96 -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 +4 -6
- package/dist/paths.js +34 -64
- package/dist/performance-observation.js +3 -5
- package/dist/progress.js +1 -1
- package/dist/recipe-assistance-context.js +6 -9
- package/dist/recipe-security.js +2 -59
- package/dist/review/knowledge.js +2 -2
- package/dist/runner.js +7 -4
- package/dist/runtime-context.js +1 -1
- package/dist/task-view.js +2 -3
- package/docs/CONTRIBUTING.md +5 -3
- package/docs/RECIPES.md +31 -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 -134
- package/library/actions/core/perps/_rewards.mjs +186 -0
- package/library/actions/core/perps/close_positions.mjs +1 -1
- package/library/actions/core/perps/place_order.mjs +167 -45
- package/library/actions/core/perps/quote_fees.mjs +61 -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/perps/close_visible_position.mjs +5 -0
- package/library/actions/extension/perps/edit_margin.mjs +4 -0
- package/library/actions/extension/perps/mutation-receipt.mjs +95 -3
- package/library/actions/extension/perps/perps.mjs +320 -3
- package/library/actions/extension/perps/place_order.mjs +3 -1
- package/library/actions/extension/perps/update_position_tpsl.mjs +4 -0
- package/library/actions/extension/platform/cdp.mjs +73 -11
- package/library/actions/harness-exports.mjs +1 -6
- package/library/actions/mobile/app/network-control.mjs +6 -8
- package/library/actions/mobile/perps/perps.mjs +216 -11
- package/library/actions/mobile/perps/place_order.mjs +3 -1
- 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/shared/perps/order-policy.mjs +177 -0
- package/library/actions/shared/wallet/fixture-accounts.mjs +84 -0
- package/library/actions/terminal/app/launch.mjs +3 -2
- package/library/actions/terminal/platform/hud.mjs +2 -1
- package/library/actions/terminal/platform/page.mjs +2 -1
- package/library/actions/terminal/platform/runtime.mjs +2 -1
- package/library/actions/terminal/wallet/_signature-log.mjs +40 -161
- package/library/actions/terminal/wallet/assert_signatures.mjs +6 -12
- package/library/actions/terminal/wallet/read_signatures.mjs +10 -9
- package/library/manifests/core.action-manifest.json +87 -13
- package/library/manifests/extension.action-manifest.json +4 -0
- package/library/manifests/mobile.action-manifest.json +12 -0
- package/package.json +8 -9
- package/site/assets/help-recipes.json +1 -0
- 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/adapters/terminal/lib/origin.mjs +0 -30
- package/adapters/terminal/lib/page-script.mjs +0 -246
- package/adapters/terminal/lib/strict-wallet.mjs +0 -138
- 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/call.js +0 -685
- package/dist/commands/last.js +0 -60
- package/dist/commands/launch/index.js +0 -109
- package/dist/commands/list-executables.js +0 -247
- package/dist/commands/manifest.js +0 -488
- package/dist/commands/parse-args.js +0 -279
- package/dist/commands/reload.js +0 -41
- package/dist/commands/run-engine.js +0 -1340
- package/dist/commands/run-report.js +0 -241
- package/dist/commands/run.js +0 -751
- package/dist/commands/shared.js +0 -323
- package/dist/commands/stop.js +0 -60
- package/dist/devices.js +0 -100
- package/dist/discovery.js +0 -15
- 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/metamask-action-validation.js +0 -68
- package/dist/network-observation.js +0 -290
- 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,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";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function perpsOrderInputFindings(nodeId, node, { ensureChecksOnly }) {
|
|
2
|
+
const action = node.action;
|
|
3
|
+
const state = typeof node.state === "string" ? node.state.toLowerCase() : void 0;
|
|
4
|
+
const createsOrder = action === "metamask.perps.place_order" || !ensureChecksOnly && (action === "metamask.perps.ensure_positions" || action === "metamask.perps.ensure_orders") && (state === "open" || state === "present");
|
|
5
|
+
if (!createsOrder) return [];
|
|
6
|
+
const findings = [];
|
|
7
|
+
const requireOneOf = (names, message) => {
|
|
8
|
+
const present = names.some((name) => {
|
|
9
|
+
const value = node[name];
|
|
10
|
+
return value !== void 0 && value !== null && value !== "";
|
|
11
|
+
});
|
|
12
|
+
if (present) return;
|
|
13
|
+
findings.push({
|
|
14
|
+
severity: "error",
|
|
15
|
+
code: "recipe.missing_param",
|
|
16
|
+
path: `workflow.nodes.${nodeId}.${names[0]}`,
|
|
17
|
+
message
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
requireOneOf(
|
|
21
|
+
["market", "symbol"],
|
|
22
|
+
`${action} requires market=<symbol> (or symbol=<symbol>) before it may create an order`
|
|
23
|
+
);
|
|
24
|
+
requireOneOf(
|
|
25
|
+
["side"],
|
|
26
|
+
`${action} requires side=long or side=short before it may create an order`
|
|
27
|
+
);
|
|
28
|
+
requireOneOf(
|
|
29
|
+
["amount", "notional"],
|
|
30
|
+
`${action} requires amount=<usd> or notional=<usd> before it may create an order`
|
|
31
|
+
);
|
|
32
|
+
return findings;
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
perpsOrderInputFindings
|
|
36
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
function emitProofFailure(json, failure) {
|
|
2
|
+
if (json) {
|
|
3
|
+
console.log(JSON.stringify({ schemaVersion: 1, status: "fail", ...failure }, null, 2));
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
console.error(`\u2717 ${failure.error.message}`);
|
|
7
|
+
console.error(` Next: ${failure.error.userAction}`);
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
emitProofFailure
|
|
11
|
+
};
|
|
@@ -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,4 +1,5 @@
|
|
|
1
1
|
import { manifestPath } from "../../paths.js";
|
|
2
|
+
import { perpsOrderInputFindings } from "../perps-order-inputs.js";
|
|
2
3
|
const terminalActions = {
|
|
3
4
|
manifestPath: () => manifestPath("terminal"),
|
|
4
5
|
semantic: [
|
|
@@ -36,7 +37,9 @@ const terminalActions = {
|
|
|
36
37
|
}
|
|
37
38
|
return standard();
|
|
38
39
|
}
|
|
39
|
-
})
|
|
40
|
+
}),
|
|
41
|
+
// ensure_positions and ensure_orders with an open or present state place an order.
|
|
42
|
+
inputFindings: (nodeId, node) => perpsOrderInputFindings(nodeId, node, { ensureChecksOnly: false })
|
|
40
43
|
};
|
|
41
44
|
export {
|
|
42
45
|
terminalActions
|
|
@@ -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",
|
|
@@ -2,7 +2,9 @@ import { terminalAppPort, terminalCdpPort } from "./surface.js";
|
|
|
2
2
|
async function terminalDoctorChecks(target) {
|
|
3
3
|
const { terminalReadiness } = await import("../../../adapters/terminal/lib/readiness.mjs");
|
|
4
4
|
const { resolveBrowser } = await import("../../../adapters/terminal/launch.mjs");
|
|
5
|
+
const { policy } = await import("../../../adapters/terminal/policy.mjs");
|
|
5
6
|
const report = await terminalReadiness({
|
|
7
|
+
policy,
|
|
6
8
|
target,
|
|
7
9
|
appPort: terminalAppPort(),
|
|
8
10
|
cdpPort: terminalCdpPort(),
|
|
@@ -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",
|
|
@@ -46,6 +46,9 @@ async function launchTerminal({ options, target, jsonOutput, stream, usage }) {
|
|
|
46
46
|
cdpPort,
|
|
47
47
|
"--app-port",
|
|
48
48
|
appPort,
|
|
49
|
+
// The Terminal's venue policy (Hyperliquid hosts, refusal, start page).
|
|
50
|
+
"--policy-module",
|
|
51
|
+
path.join(runnerDir, "adapters", "terminal", "policy.mjs"),
|
|
49
52
|
"--signer",
|
|
50
53
|
str(options, "signer") ?? process.env.TERMINAL_SIGNER ?? "extension",
|
|
51
54
|
"--account",
|
|
@@ -3,7 +3,14 @@ import { runnerDir } from "../../paths.js";
|
|
|
3
3
|
const terminalHarness = {
|
|
4
4
|
install: { entry: "adapters/terminal/inject.mjs", fallback: "adapters/terminal/inject.mjs", node: true },
|
|
5
5
|
cleanup: { entry: "adapters/terminal/cleanup.mjs", fallback: "adapters/terminal/cleanup.mjs", node: true },
|
|
6
|
-
verify: () => ({
|
|
6
|
+
verify: () => ({
|
|
7
|
+
command: process.execPath,
|
|
8
|
+
prefixArgs: [
|
|
9
|
+
path.join(runnerDir, "adapters", "terminal", "verify.mjs"),
|
|
10
|
+
"--policy-module",
|
|
11
|
+
path.join(runnerDir, "adapters", "terminal", "policy.mjs")
|
|
12
|
+
]
|
|
13
|
+
}),
|
|
7
14
|
restart: "mm-harness launch"
|
|
8
15
|
};
|
|
9
16
|
const terminalRuntimeContext = {
|
|
@@ -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,17 +13,43 @@ 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
|
-
backend: async (_target, env, artifactsDir) => (await import("
|
|
43
|
+
backend: async (_target, env, artifactsDir) => (await import("../extension/network-observer.js")).createExtensionNetworkBackend(env, artifactsDir)
|
|
21
44
|
},
|
|
22
45
|
performance: {
|
|
23
|
-
|
|
24
|
-
|
|
46
|
+
start: async (context) => {
|
|
47
|
+
const observation = await import("../../performance-observation.js");
|
|
48
|
+
return observation.startRunPerformanceObservation({
|
|
49
|
+
backend: (target, env, ports) => observation.createExtensionPerformanceObserver(target, env, ports),
|
|
50
|
+
platform: (env) => devicePlatformFromEnv(env)
|
|
51
|
+
}, context);
|
|
52
|
+
}
|
|
25
53
|
}
|
|
26
54
|
};
|
|
27
55
|
export {
|
|
@@ -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];
|
|
@@ -38,7 +39,9 @@ const terminalSurface = defineAdapter({
|
|
|
38
39
|
},
|
|
39
40
|
async runtimeStatus(target) {
|
|
40
41
|
const { terminalReadiness: terminalReadiness2 } = await import("../../../adapters/terminal/lib/readiness.mjs");
|
|
42
|
+
const { policy } = await import("../../../adapters/terminal/policy.mjs");
|
|
41
43
|
const report = await terminalReadiness2({
|
|
44
|
+
policy,
|
|
42
45
|
target: path.resolve(target),
|
|
43
46
|
appPort: terminalAppPort(),
|
|
44
47
|
cdpPort: terminalCdpPort(),
|
|
@@ -98,6 +101,11 @@ const terminalSurface = defineAdapter({
|
|
|
98
101
|
appLogSource(target) {
|
|
99
102
|
return { label: "app-console", path: terminalRuntimeFile(target, TERMINAL_CONSOLE_FILES.app) };
|
|
100
103
|
},
|
|
104
|
+
detect: {
|
|
105
|
+
remote: (url) => url.includes("va-mmcx-terminal"),
|
|
106
|
+
files: (target) => checkoutHasDir(target, "src/features/perpetuals") && ["next.config.ts", "next.config.mjs", "next.config.js"].some((file) => checkoutHas(target, file))
|
|
107
|
+
},
|
|
108
|
+
flags: { launch: ["freshProfile", "headless", "headful"] },
|
|
101
109
|
hints: {
|
|
102
110
|
launch: "mm-harness launch --adapter terminal --cdp-port <port> --watcher-port <app port>",
|
|
103
111
|
relaunch: "mm-harness launch --adapter terminal --fresh-profile",
|
package/dist/adapters.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
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 { liveAdapterProcessTimeoutMs, runLiveAdapterScript, runNetworkCaptureAction } 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";
|
|
10
|
-
import { handleRunNetworkAction } from "./network-observation.js";
|
|
11
11
|
import { handleRunPerformanceAction } from "./performance-observation.js";
|
|
12
12
|
function simpleAdapter(action, executor) {
|
|
13
13
|
return {
|
|
@@ -99,6 +99,12 @@ function liveRuntimeConfigured(platform, node) {
|
|
|
99
99
|
if (!getAdapterSurface(platform).actions.liveNeedsCdpPort) return true;
|
|
100
100
|
return Boolean(node.cdp_port ?? process.env.CDP_PORT ?? process.env.RECIPE_CDP_PORT);
|
|
101
101
|
}
|
|
102
|
+
const IMMEDIATE_CLOSE_ALLOWANCE_MS = 18e4;
|
|
103
|
+
function withImmediateCloseBudget(action, node) {
|
|
104
|
+
if (action !== `${LIBRARY_ACTION_NAMESPACE}.perps.place_order`) return node;
|
|
105
|
+
if (node.close_immediately !== true && node.closeImmediately !== true) return node;
|
|
106
|
+
return { ...node, live_adapter_timeout_ms: liveAdapterProcessTimeoutMs(node) + IMMEDIATE_CLOSE_ALLOWANCE_MS };
|
|
107
|
+
}
|
|
102
108
|
async function runLiveFirst(platform, action, node, context, forceLive = false, preparedLiveAdapters) {
|
|
103
109
|
if (node.allow_static_placeholder === true) {
|
|
104
110
|
throw new Error(
|
|
@@ -109,9 +115,12 @@ async function runLiveFirst(platform, action, node, context, forceLive = false,
|
|
|
109
115
|
const live = await runLiveAdapterScript({
|
|
110
116
|
platform,
|
|
111
117
|
action,
|
|
112
|
-
|
|
118
|
+
namespace: LIBRARY_ACTION_NAMESPACE,
|
|
119
|
+
node: withImmediateCloseBudget(action, node),
|
|
113
120
|
context,
|
|
114
|
-
prepared: preparedLiveAdapters?.get(action)
|
|
121
|
+
prepared: preparedLiveAdapters?.get(action),
|
|
122
|
+
contextExtras: trustedMutationContextExtras(context),
|
|
123
|
+
tsxCandidates: liveTsxCandidates()
|
|
115
124
|
});
|
|
116
125
|
if (!live) return null;
|
|
117
126
|
const liveResult = isRecord(live.result) ? live.result : { result: live.result };
|
|
@@ -127,6 +136,15 @@ function liveAdapterPathHint(platform, action) {
|
|
|
127
136
|
}
|
|
128
137
|
return `library/actions/${platform}/${action.replaceAll(".", "/")}.mjs`;
|
|
129
138
|
}
|
|
139
|
+
async function handleRunNetworkAction(platform, action, node, context) {
|
|
140
|
+
if (!getAdapterSurface(platform).observation?.network?.actions) return null;
|
|
141
|
+
if (action === "app.network_assert") {
|
|
142
|
+
const assertion = await import("../library/actions/shared/app/network-assert.mjs");
|
|
143
|
+
return { output: await assertion.assertNetwork({ action, node, context }) };
|
|
144
|
+
}
|
|
145
|
+
if (action !== "app.network_capture") return null;
|
|
146
|
+
return runNetworkCaptureAction(platform, node, context);
|
|
147
|
+
}
|
|
130
148
|
async function semanticResult(platform, action, node, context, forceLive = false, preparedLiveAdapters) {
|
|
131
149
|
const performanceAction = await handleRunPerformanceAction(
|
|
132
150
|
platform,
|
|
@@ -364,7 +382,9 @@ function createMetaMaskAdapters(adapter, declaredCustomActions = [], preparedLiv
|
|
|
364
382
|
return adapters;
|
|
365
383
|
}
|
|
366
384
|
export {
|
|
385
|
+
IMMEDIATE_CLOSE_ALLOWANCE_MS,
|
|
367
386
|
createMetaMaskAdapters,
|
|
368
387
|
createMetaMaskUiTransport,
|
|
369
|
-
normalizeUiWaitNode
|
|
388
|
+
normalizeUiWaitNode,
|
|
389
|
+
withImmediateCloseBudget
|
|
370
390
|
};
|
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,
|