@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
package/dist/commands/shared.js
DELETED
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
import { trackCheckoutChild } from "../checkout-lock.js";
|
|
2
|
-
import { recordCommandOutput, recordCommandStage } from "../command-journal.js";
|
|
3
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
4
|
-
import { StringDecoder } from "node:string_decoder";
|
|
5
|
-
import { OperationOutputTail } from "@farmslot/recipe-runner/runtime/operation";
|
|
6
|
-
import path from "node:path";
|
|
7
|
-
import { detectAdapter } from "../harness.js";
|
|
8
|
-
import { colorHumanMessage } from "../cli-color.js";
|
|
9
|
-
import { resolveLeafInvoke, shellLeafMissing } from "../leaf-invoke.js";
|
|
10
|
-
import { adapterRegistry } from "../adapters/registry.js";
|
|
11
|
-
const EXIT = { ok: 0, runtime: 1, usage: 2, infra: 3, bounded: 4, validation: 5 };
|
|
12
|
-
function writeInteractiveProgress(json, message, {
|
|
13
|
-
stdoutIsTTY = Boolean(process.stdout.isTTY),
|
|
14
|
-
stream = process.stderr
|
|
15
|
-
} = {}) {
|
|
16
|
-
if (json || !stdoutIsTTY) return false;
|
|
17
|
-
stream.write(`${colorHumanMessage(message, { stream })}
|
|
18
|
-
`);
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
function parseFlags(argv, booleans) {
|
|
22
|
-
const positional = [];
|
|
23
|
-
const options = {};
|
|
24
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
25
|
-
const arg = argv[i];
|
|
26
|
-
if (!arg.startsWith("--")) {
|
|
27
|
-
positional.push(arg);
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
const body = arg.slice(2);
|
|
31
|
-
const eq = body.indexOf("=");
|
|
32
|
-
const rawKey = eq === -1 ? body : body.slice(0, eq);
|
|
33
|
-
const inline = eq === -1 ? void 0 : body.slice(eq + 1);
|
|
34
|
-
const key = rawKey.replace(/-([a-z])/gu, (_, c) => c.toUpperCase());
|
|
35
|
-
if (booleans.has(key)) {
|
|
36
|
-
options[key] = inline === void 0 ? true : inline !== "false";
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if (inline !== void 0) {
|
|
40
|
-
options[key] = inline;
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
const next = argv[i + 1];
|
|
44
|
-
if (next === void 0 || next.startsWith("--")) {
|
|
45
|
-
options[key] = true;
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
options[key] = next;
|
|
49
|
-
i += 1;
|
|
50
|
-
}
|
|
51
|
-
return { positional, options };
|
|
52
|
-
}
|
|
53
|
-
function str(options, key) {
|
|
54
|
-
const value = options[key];
|
|
55
|
-
return typeof value === "string" ? value : void 0;
|
|
56
|
-
}
|
|
57
|
-
function flag(options, key) {
|
|
58
|
-
return options[key] === true;
|
|
59
|
-
}
|
|
60
|
-
function targetOf(options) {
|
|
61
|
-
return path.resolve(str(options, "target") ?? process.cwd());
|
|
62
|
-
}
|
|
63
|
-
function resolveAdapter(options, target, hint) {
|
|
64
|
-
const platform = str(options, "platform");
|
|
65
|
-
const explicit = str(options, "adapter") ?? (platform === "ios" || platform === "android" ? "mobile" : platform);
|
|
66
|
-
if (explicit && adapterRegistry.has(explicit)) return explicit;
|
|
67
|
-
if (hint) return hint;
|
|
68
|
-
return detectAdapter(target);
|
|
69
|
-
}
|
|
70
|
-
function scriptOverride(scriptPath) {
|
|
71
|
-
const stem = path.basename(scriptPath).replace(/[^A-Za-z0-9]/gu, "_").toUpperCase();
|
|
72
|
-
return process.env[`MM_HARNESS_SCRIPT_BIN_${stem}`];
|
|
73
|
-
}
|
|
74
|
-
function spawnScript(script, args, cwd, json, env) {
|
|
75
|
-
const isNodeScript = script === process.execPath && args.length > 0;
|
|
76
|
-
const stem = isNodeScript ? path.basename(args[0]).replace(/[^A-Za-z0-9]/gu, "_").toUpperCase() : path.basename(script).replace(/[^A-Za-z0-9]/gu, "_").toUpperCase();
|
|
77
|
-
const override = process.env[`MM_HARNESS_SCRIPT_BIN_${stem}`];
|
|
78
|
-
const bin = override ?? script;
|
|
79
|
-
const directArgs = override !== void 0 && isNodeScript ? args.slice(1) : args;
|
|
80
|
-
if (shellLeafMissing(bin)) {
|
|
81
|
-
const message = `leaf could not start: ${path.basename(bin)} (ENOENT)
|
|
82
|
-
Next: reinstall mm-harness (npm i -g @deeeed/metamask-harness) \u2014 the shell leaf is missing or not executable`;
|
|
83
|
-
process.stderr.write(`${message}
|
|
84
|
-
`);
|
|
85
|
-
return { status: 1, output: message };
|
|
86
|
-
}
|
|
87
|
-
const { bin: invokeBin, args: spawnArgs } = resolveLeafInvoke(bin, directArgs);
|
|
88
|
-
recordCommandStage(path.basename(isNodeScript ? args[0] : script));
|
|
89
|
-
const result = spawnSync(invokeBin, spawnArgs, {
|
|
90
|
-
cwd,
|
|
91
|
-
encoding: "utf8",
|
|
92
|
-
env: env ? { ...process.env, ...env } : process.env,
|
|
93
|
-
maxBuffer: 64 * 1024 * 1024
|
|
94
|
-
});
|
|
95
|
-
if (result.error) {
|
|
96
|
-
const leaf = isNodeScript ? path.basename(args[0]) : path.basename(script);
|
|
97
|
-
const code = result.error.code ?? "ESPAWN";
|
|
98
|
-
const message = `leaf could not start: ${leaf} (${code})
|
|
99
|
-
Next: reinstall mm-harness (npm i -g @deeeed/metamask-harness) \u2014 the shell leaf is missing or not executable`;
|
|
100
|
-
process.stderr.write(`${message}
|
|
101
|
-
`);
|
|
102
|
-
return { status: 1, output: message };
|
|
103
|
-
}
|
|
104
|
-
const output = `${result.stdout ?? ""}${result.stderr ?? ""}`;
|
|
105
|
-
recordCommandOutput(output);
|
|
106
|
-
if (!json && output) process.stderr.write(output);
|
|
107
|
-
return { status: result.status ?? 1, output };
|
|
108
|
-
}
|
|
109
|
-
function spawnInherit(script, args, cwd) {
|
|
110
|
-
const isNodeScript = script === process.execPath && args.length > 0;
|
|
111
|
-
const stem = (isNodeScript ? path.basename(args[0]) : path.basename(script)).replace(/[^A-Za-z0-9]/gu, "_").toUpperCase();
|
|
112
|
-
const override = process.env[`MM_HARNESS_SCRIPT_BIN_${stem}`];
|
|
113
|
-
const bin = override ?? script;
|
|
114
|
-
const directArgs = override !== void 0 && isNodeScript ? args.slice(1) : args;
|
|
115
|
-
const { bin: invokeBin, args: spawnArgs } = resolveLeafInvoke(bin, directArgs);
|
|
116
|
-
const result = spawnSync(invokeBin, spawnArgs, { cwd, stdio: "inherit", env: process.env });
|
|
117
|
-
if (result.error) {
|
|
118
|
-
const leaf = isNodeScript ? path.basename(args[0]) : path.basename(script);
|
|
119
|
-
const code = result.error.code ?? "ESPAWN";
|
|
120
|
-
process.stderr.write(
|
|
121
|
-
`leaf could not start: ${leaf} (${code})
|
|
122
|
-
Next: reinstall mm-harness (npm i -g @deeeed/metamask-harness) \u2014 the leaf is missing or not executable
|
|
123
|
-
`
|
|
124
|
-
);
|
|
125
|
-
return 1;
|
|
126
|
-
}
|
|
127
|
-
if (result.status !== null) return result.status;
|
|
128
|
-
return result.signal === "SIGINT" || result.signal === "SIGTERM" ? 0 : 1;
|
|
129
|
-
}
|
|
130
|
-
function spawnScriptStreaming(script, args, cwd, options) {
|
|
131
|
-
const spawnOptions = options && ("env" in options || "timeoutMs" in options || "forward" in options || "capture" in options || "stdin" in options || "stage" in options) ? options : { env: options };
|
|
132
|
-
const isNodeScript = script === process.execPath && args.length > 0;
|
|
133
|
-
const stem = isNodeScript ? path.basename(args[0]).replace(/[^A-Za-z0-9]/gu, "_").toUpperCase() : path.basename(script).replace(/[^A-Za-z0-9]/gu, "_").toUpperCase();
|
|
134
|
-
const override = process.env[`MM_HARNESS_SCRIPT_BIN_${stem}`];
|
|
135
|
-
const bin = override ?? script;
|
|
136
|
-
const directArgs = override !== void 0 && isNodeScript ? args.slice(1) : args;
|
|
137
|
-
if (shellLeafMissing(bin)) {
|
|
138
|
-
const message = `leaf could not start: ${path.basename(bin)} (ENOENT)
|
|
139
|
-
Next: reinstall mm-harness (npm i -g @deeeed/metamask-harness) \u2014 the shell leaf is missing or not executable`;
|
|
140
|
-
if (spawnOptions.forward !== "none") process.stderr.write(`${message}
|
|
141
|
-
`);
|
|
142
|
-
return Promise.resolve({ status: 1, output: message });
|
|
143
|
-
}
|
|
144
|
-
const { bin: invokeBin, args: spawnArgs } = resolveLeafInvoke(bin, directArgs);
|
|
145
|
-
recordCommandStage(spawnOptions.stage ?? path.basename(isNodeScript ? args[0] : script));
|
|
146
|
-
return new Promise((resolve, reject) => {
|
|
147
|
-
const ownsProcessGroup = process.platform !== "win32";
|
|
148
|
-
const child = spawn(invokeBin, spawnArgs, {
|
|
149
|
-
cwd,
|
|
150
|
-
env: spawnOptions.env ? { ...process.env, ...spawnOptions.env } : process.env,
|
|
151
|
-
stdio: [spawnOptions.stdin ?? "ignore", "pipe", "pipe"],
|
|
152
|
-
detached: ownsProcessGroup
|
|
153
|
-
});
|
|
154
|
-
let untrack;
|
|
155
|
-
try {
|
|
156
|
-
untrack = child.pid ? trackCheckoutChild(cwd, child.pid, ownsProcessGroup) : void 0;
|
|
157
|
-
} catch (error) {
|
|
158
|
-
child.once("error", reject);
|
|
159
|
-
child.once("close", () => reject(error));
|
|
160
|
-
try {
|
|
161
|
-
if (ownsProcessGroup && child.pid) process.kill(-child.pid, "SIGKILL");
|
|
162
|
-
else child.kill("SIGKILL");
|
|
163
|
-
} catch (killError) {
|
|
164
|
-
if (killError.code !== "ESRCH") reject(killError);
|
|
165
|
-
}
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
const captured = new OperationOutputTail();
|
|
169
|
-
let settled = false;
|
|
170
|
-
let didTimeout = false;
|
|
171
|
-
let escalation;
|
|
172
|
-
let forwardedParentSignal;
|
|
173
|
-
let parentSignalFallback;
|
|
174
|
-
const parentSignals = ["SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT"];
|
|
175
|
-
const removeParentSignalHandlers = () => {
|
|
176
|
-
for (const signal of parentSignals) process.removeListener(signal, parentSignalHandlers[signal]);
|
|
177
|
-
};
|
|
178
|
-
const finish = (result) => {
|
|
179
|
-
if (settled) return;
|
|
180
|
-
settled = true;
|
|
181
|
-
if (timer) clearTimeout(timer);
|
|
182
|
-
if (escalation) clearTimeout(escalation);
|
|
183
|
-
if (parentSignalFallback) clearTimeout(parentSignalFallback);
|
|
184
|
-
removeParentSignalHandlers();
|
|
185
|
-
resolve(result);
|
|
186
|
-
};
|
|
187
|
-
const signalChildTree = (signal) => {
|
|
188
|
-
try {
|
|
189
|
-
if (ownsProcessGroup && child.pid) process.kill(-child.pid, signal);
|
|
190
|
-
else child.kill(signal);
|
|
191
|
-
} catch {
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
const exitFromForwardedSignal = () => {
|
|
195
|
-
if (!forwardedParentSignal) return;
|
|
196
|
-
const signal = forwardedParentSignal;
|
|
197
|
-
forwardedParentSignal = void 0;
|
|
198
|
-
if (parentSignalFallback) clearTimeout(parentSignalFallback);
|
|
199
|
-
process.kill(process.pid, signal);
|
|
200
|
-
};
|
|
201
|
-
const parentSignalHandlers = Object.fromEntries(parentSignals.map((signal) => [signal, () => {
|
|
202
|
-
if (forwardedParentSignal) return;
|
|
203
|
-
forwardedParentSignal = signal;
|
|
204
|
-
signalChildTree(signal);
|
|
205
|
-
removeParentSignalHandlers();
|
|
206
|
-
if (Number(spawnOptions.timeoutMs) > 0) parentSignalFallback = setTimeout(() => {
|
|
207
|
-
signalChildTree("SIGKILL");
|
|
208
|
-
exitFromForwardedSignal();
|
|
209
|
-
}, 1e3);
|
|
210
|
-
}]));
|
|
211
|
-
if (ownsProcessGroup) {
|
|
212
|
-
for (const signal of parentSignals) process.once(signal, parentSignalHandlers[signal]);
|
|
213
|
-
}
|
|
214
|
-
const timeoutMs = spawnOptions.timeoutMs;
|
|
215
|
-
const timer = Number.isFinite(timeoutMs) && Number(timeoutMs) > 0 ? setTimeout(() => {
|
|
216
|
-
didTimeout = true;
|
|
217
|
-
const message = `leaf timed out after ${String(timeoutMs)}ms: ${path.basename(script)}`;
|
|
218
|
-
captured.append(`
|
|
219
|
-
${message}
|
|
220
|
-
`);
|
|
221
|
-
if (spawnOptions.forward !== "none") process.stderr.write(`${message}
|
|
222
|
-
`);
|
|
223
|
-
signalChildTree("SIGTERM");
|
|
224
|
-
escalation = setTimeout(() => {
|
|
225
|
-
signalChildTree("SIGKILL");
|
|
226
|
-
finish({ status: 1, output: captured.toString(), timedOut: true, timeoutMs: Number(timeoutMs) });
|
|
227
|
-
}, 1e3);
|
|
228
|
-
}, Number(timeoutMs)) : void 0;
|
|
229
|
-
const decoders = [new StringDecoder("utf8"), new StringDecoder("utf8")];
|
|
230
|
-
const tee = (chunk, stdout = false) => {
|
|
231
|
-
if (spawnOptions.capture !== false) captured.append(decoders[stdout ? 0 : 1].write(chunk));
|
|
232
|
-
recordCommandOutput(chunk);
|
|
233
|
-
if (spawnOptions.forward !== "none") {
|
|
234
|
-
(stdout && spawnOptions.forward === "original" ? process.stdout : process.stderr).write(chunk);
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
child.stdout?.on("data", (chunk) => tee(chunk, true));
|
|
238
|
-
child.stderr?.on("data", tee);
|
|
239
|
-
child.on("error", (error) => {
|
|
240
|
-
const leaf = isNodeScript ? path.basename(args[0]) : path.basename(script);
|
|
241
|
-
const code = error.code ?? "ESPAWN";
|
|
242
|
-
const message = `leaf could not start: ${leaf} (${code})
|
|
243
|
-
Next: reinstall mm-harness (npm i -g @deeeed/metamask-harness) \u2014 the shell leaf is missing or not executable`;
|
|
244
|
-
if (spawnOptions.forward !== "none") process.stderr.write(`${message}
|
|
245
|
-
`);
|
|
246
|
-
finish({ status: 1, output: message, error });
|
|
247
|
-
});
|
|
248
|
-
child.on("exit", () => {
|
|
249
|
-
if (forwardedParentSignal) {
|
|
250
|
-
exitFromForwardedSignal();
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
if (!didTimeout) return;
|
|
254
|
-
signalChildTree("SIGKILL");
|
|
255
|
-
finish({ status: 1, output: captured.toString(), timedOut: true, timeoutMs: Number(timeoutMs) });
|
|
256
|
-
});
|
|
257
|
-
child.on("close", (status) => {
|
|
258
|
-
if (status !== null) untrack?.();
|
|
259
|
-
if (spawnOptions.capture !== false) captured.append(decoders.map((decoder) => decoder.end()).join(""));
|
|
260
|
-
if (didTimeout) signalChildTree("SIGKILL");
|
|
261
|
-
finish({
|
|
262
|
-
status: didTimeout ? 1 : status ?? 1,
|
|
263
|
-
output: captured.toString(),
|
|
264
|
-
...didTimeout ? { timedOut: true, timeoutMs: Number(timeoutMs) } : {}
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
import { ADAPTER_DETECT_NEXT } from "../harness.js";
|
|
270
|
-
function usageOut(json, command, message, userAction) {
|
|
271
|
-
if (json) {
|
|
272
|
-
console.log(
|
|
273
|
-
JSON.stringify(
|
|
274
|
-
{ schemaVersion: 1, command, status: "fail", exitCode: EXIT.usage, error: { code: "USAGE", message, userAction } },
|
|
275
|
-
null,
|
|
276
|
-
2
|
|
277
|
-
)
|
|
278
|
-
);
|
|
279
|
-
} else {
|
|
280
|
-
console.error(`\u2717 mm-harness ${command}: ${message}
|
|
281
|
-
Next: ${userAction}`);
|
|
282
|
-
}
|
|
283
|
-
return EXIT.usage;
|
|
284
|
-
}
|
|
285
|
-
function checkoutBusyOut(json, command, message, lockPath) {
|
|
286
|
-
const userAction = `wait for the current owner, or inspect ${lockPath} if its process has exited`;
|
|
287
|
-
if (json) {
|
|
288
|
-
console.log(
|
|
289
|
-
JSON.stringify(
|
|
290
|
-
{
|
|
291
|
-
schemaVersion: 1,
|
|
292
|
-
command,
|
|
293
|
-
status: "fail",
|
|
294
|
-
exitCode: EXIT.bounded,
|
|
295
|
-
recoverable: false,
|
|
296
|
-
error: { code: "SANDBOX_BUSY", message, userAction }
|
|
297
|
-
},
|
|
298
|
-
null,
|
|
299
|
-
2
|
|
300
|
-
)
|
|
301
|
-
);
|
|
302
|
-
} else {
|
|
303
|
-
console.error(`\u2717 mm-harness ${command}: ${message}
|
|
304
|
-
Next: ${userAction}`);
|
|
305
|
-
}
|
|
306
|
-
return EXIT.bounded;
|
|
307
|
-
}
|
|
308
|
-
export {
|
|
309
|
-
ADAPTER_DETECT_NEXT,
|
|
310
|
-
EXIT,
|
|
311
|
-
checkoutBusyOut,
|
|
312
|
-
flag,
|
|
313
|
-
parseFlags,
|
|
314
|
-
resolveAdapter,
|
|
315
|
-
scriptOverride,
|
|
316
|
-
spawnInherit,
|
|
317
|
-
spawnScript,
|
|
318
|
-
spawnScriptStreaming,
|
|
319
|
-
str,
|
|
320
|
-
targetOf,
|
|
321
|
-
usageOut,
|
|
322
|
-
writeInteractiveProgress
|
|
323
|
-
};
|
package/dist/commands/stop.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { color } from "../cli-color.js";
|
|
2
|
-
import { getAdapterSurface } from "../adapters/surface.js";
|
|
3
|
-
import { usageOut } from "./shared.js";
|
|
4
|
-
import { stopProjectCollector } from "../../library/actions/shared/analytics/collector.mjs";
|
|
5
|
-
import {
|
|
6
|
-
parseArgs,
|
|
7
|
-
optionFlag,
|
|
8
|
-
optionString,
|
|
9
|
-
resolveAdapter,
|
|
10
|
-
shellQuote
|
|
11
|
-
} from "./parse-args.js";
|
|
12
|
-
async function handleStop(argv) {
|
|
13
|
-
const { options } = parseArgs(argv, "stop");
|
|
14
|
-
const json = optionFlag(options, "json");
|
|
15
|
-
const { adapter, target } = resolveAdapter(options);
|
|
16
|
-
const surface = getAdapterSurface(adapter);
|
|
17
|
-
surface.resolveSlotPorts(target);
|
|
18
|
-
const explicitPort = optionString(options, "port") ?? optionString(options, "watcherPort");
|
|
19
|
-
if (explicitPort) {
|
|
20
|
-
process.env.WATCHER_PORT = explicitPort;
|
|
21
|
-
process.env.METRO_PORT = explicitPort;
|
|
22
|
-
}
|
|
23
|
-
const stop = surface.devServer.stop(target);
|
|
24
|
-
if (stop.kind === "headless") {
|
|
25
|
-
return usageOut(json, "stop", stop.message, stop.userAction);
|
|
26
|
-
}
|
|
27
|
-
const collector = await stopProjectCollector(target);
|
|
28
|
-
const signalled = (stop.signalled ?? 0) + (collector.stopped ? 1 : 0);
|
|
29
|
-
const summary = collector.stopped ? `${stop.summary}; stopped analytics collector ${collector.pid}` : stop.summary;
|
|
30
|
-
const next = surface.devServer.afterStop?.(target);
|
|
31
|
-
const userAction = `mm-harness status --target ${shellQuote(target)} --json`;
|
|
32
|
-
if (json) {
|
|
33
|
-
console.log(
|
|
34
|
-
JSON.stringify(
|
|
35
|
-
{
|
|
36
|
-
schemaVersion: 1,
|
|
37
|
-
command: "stop",
|
|
38
|
-
adapter,
|
|
39
|
-
target,
|
|
40
|
-
status: stop.status === 0 ? "pass" : "fail",
|
|
41
|
-
...stop.signalled !== void 0 || collector.stopped ? { signalled } : {},
|
|
42
|
-
exitCode: stop.status,
|
|
43
|
-
...stop.output ? { output: stop.output } : {},
|
|
44
|
-
...stop.status === 0 ? next ? { next } : {} : { error: { code: "DEV_SERVER_STOP_FAILED", message: summary, userAction } }
|
|
45
|
-
},
|
|
46
|
-
null,
|
|
47
|
-
2
|
|
48
|
-
)
|
|
49
|
-
);
|
|
50
|
-
} else {
|
|
51
|
-
if (stop.output) process.stderr.write(`${stop.output}
|
|
52
|
-
`);
|
|
53
|
-
console.error(`${color(stop.status === 0 ? "ok" : "err", stop.status === 0 ? "\u2713" : "\u2717")} ${summary}`);
|
|
54
|
-
if (stop.status !== 0 || next) console.error(` Next: ${stop.status === 0 ? next : userAction}`);
|
|
55
|
-
}
|
|
56
|
-
return stop.status;
|
|
57
|
-
}
|
|
58
|
-
export {
|
|
59
|
-
handleStop
|
|
60
|
-
};
|
package/dist/devices.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from "node:child_process";
|
|
2
|
-
import { resolveMobileToolPath } from "../library/actions/mobile/platform/tool-paths.mjs";
|
|
3
|
-
const IOS_DEVICE_DISCOVERY_TIMEOUT_MS = 3e4;
|
|
4
|
-
function reportProbeFailure(errors, platform, error) {
|
|
5
|
-
const code = error?.code;
|
|
6
|
-
if (code === "ENOENT") return;
|
|
7
|
-
const timeoutSeconds = platform === "ios" ? IOS_DEVICE_DISCOVERY_TIMEOUT_MS / 1e3 : 5;
|
|
8
|
-
const reason = code === "ETIMEDOUT" ? `timed out after ${timeoutSeconds} seconds` : "failed";
|
|
9
|
-
const probeCode = code ?? error?.status;
|
|
10
|
-
errors.push({
|
|
11
|
-
platform,
|
|
12
|
-
message: `${platform} device discovery ${reason}; device availability is unknown.`,
|
|
13
|
-
userAction: platform === "ios" ? "xcrun simctl list devices booted -j" : "adb devices -l",
|
|
14
|
-
...probeCode !== void 0 ? { probeCode } : {}
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
function listConnectedDevices(platform, errors = []) {
|
|
18
|
-
const devices = [];
|
|
19
|
-
if (!platform || platform === "android") devices.push(...listAndroidDevices(errors));
|
|
20
|
-
if (!platform || platform === "ios") devices.push(...listIosSimulators("booted", errors));
|
|
21
|
-
return devices;
|
|
22
|
-
}
|
|
23
|
-
function findAvailableIosSimulatorById(id, errors = []) {
|
|
24
|
-
for (const simulator of listIosSimulators("available", errors)) {
|
|
25
|
-
if (simulator.id === id) return simulator;
|
|
26
|
-
}
|
|
27
|
-
return void 0;
|
|
28
|
-
}
|
|
29
|
-
function listAndroidDevices(errors) {
|
|
30
|
-
const adbPath = resolveMobileToolPath("adb");
|
|
31
|
-
if (!adbPath) return [];
|
|
32
|
-
let output;
|
|
33
|
-
try {
|
|
34
|
-
output = execFileSync(adbPath, ["devices", "-l"], {
|
|
35
|
-
encoding: "utf8",
|
|
36
|
-
timeout: 5e3,
|
|
37
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
38
|
-
});
|
|
39
|
-
} catch (error) {
|
|
40
|
-
reportProbeFailure(errors, "android", error);
|
|
41
|
-
return [];
|
|
42
|
-
}
|
|
43
|
-
if (!output.trimStart().startsWith("List of devices attached")) {
|
|
44
|
-
errors.push({ platform: "android", message: "Android device discovery returned an invalid response; device availability is unknown.", userAction: "adb devices -l" });
|
|
45
|
-
return [];
|
|
46
|
-
}
|
|
47
|
-
const devices = [];
|
|
48
|
-
for (const line of output.split("\n").slice(1)) {
|
|
49
|
-
const trimmed = line.trim();
|
|
50
|
-
if (!trimmed) continue;
|
|
51
|
-
const fields = trimmed.split(/\s+/u);
|
|
52
|
-
const id = fields[0];
|
|
53
|
-
const state = fields[1] ?? "unknown";
|
|
54
|
-
if (!id) continue;
|
|
55
|
-
const modelField = fields.find((f) => f.startsWith("model:"));
|
|
56
|
-
const name = modelField ? modelField.slice("model:".length) : void 0;
|
|
57
|
-
devices.push({ platform: "android", id, state, ...name ? { name } : {} });
|
|
58
|
-
}
|
|
59
|
-
return devices;
|
|
60
|
-
}
|
|
61
|
-
function listIosSimulators(scope, errors) {
|
|
62
|
-
let output;
|
|
63
|
-
try {
|
|
64
|
-
output = execFileSync("xcrun", ["simctl", "list", "devices", scope, "-j"], {
|
|
65
|
-
encoding: "utf8",
|
|
66
|
-
timeout: IOS_DEVICE_DISCOVERY_TIMEOUT_MS,
|
|
67
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
68
|
-
});
|
|
69
|
-
} catch (error) {
|
|
70
|
-
reportProbeFailure(errors, "ios", error);
|
|
71
|
-
return [];
|
|
72
|
-
}
|
|
73
|
-
let parsed;
|
|
74
|
-
try {
|
|
75
|
-
parsed = JSON.parse(output);
|
|
76
|
-
if (!parsed?.devices || typeof parsed.devices !== "object" || Array.isArray(parsed.devices) || Object.values(parsed.devices).some((devices2) => !Array.isArray(devices2) || devices2.some((device) => !device || typeof device.udid !== "string"))) {
|
|
77
|
-
throw new Error("Invalid simctl device inventory");
|
|
78
|
-
}
|
|
79
|
-
} catch {
|
|
80
|
-
errors.push({ platform: "ios", message: "iOS device discovery returned an invalid response; device availability is unknown.", userAction: `xcrun simctl list devices ${scope} -j` });
|
|
81
|
-
return [];
|
|
82
|
-
}
|
|
83
|
-
const devices = [];
|
|
84
|
-
for (const runtimeDevices of Object.values(parsed.devices ?? {})) {
|
|
85
|
-
for (const device of runtimeDevices) {
|
|
86
|
-
if (!device.udid) continue;
|
|
87
|
-
devices.push({
|
|
88
|
-
platform: "ios",
|
|
89
|
-
id: device.udid,
|
|
90
|
-
state: device.state ?? "unknown",
|
|
91
|
-
...device.name ? { name: device.name } : {}
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return devices;
|
|
96
|
-
}
|
|
97
|
-
export {
|
|
98
|
-
findAvailableIosSimulatorById,
|
|
99
|
-
listConnectedDevices
|
|
100
|
-
};
|
package/dist/discovery.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { assessRecipe } from "@farmslot/recipe-cli";
|
|
2
|
-
import {
|
|
3
|
-
loadRecipeLibraries
|
|
4
|
-
} from "@farmslot/recipe-runner";
|
|
5
|
-
import { resolveActionManifest } from "./manifest.js";
|
|
6
|
-
async function runnableLibraryRecipes(adapter, sources) {
|
|
7
|
-
const resolution = await loadRecipeLibraries(sources, { adapter });
|
|
8
|
-
const { manifest } = await resolveActionManifest(adapter, void 0, sources);
|
|
9
|
-
return [...resolution.recipes.values()].filter(
|
|
10
|
-
(recipe) => assessRecipe({ resolution, manifest }, recipe).length === 0
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
export {
|
|
14
|
-
runnableLibraryRecipes
|
|
15
|
-
};
|