@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.
Files changed (210) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +1 -1
  3. package/adapters/extension/ensure-browser.sh +2 -2
  4. package/adapters/extension/inject.mjs +0 -1
  5. package/adapters/extension/launch-browser.cjs +39 -613
  6. package/adapters/extension/readiness.mjs +2 -5
  7. package/adapters/extension/reattach.sh +2 -2
  8. package/adapters/extension/stamp-runtime-title.cjs +1 -1
  9. package/adapters/manifest.json +2 -34
  10. package/adapters/mobile/bridge-runtime/cdp-bridge.cjs +57 -1358
  11. package/adapters/mobile/bridge-runtime/teaching.cjs +20 -0
  12. package/adapters/mobile/inject.sh +16 -0
  13. package/adapters/mobile/launch-console-forwarder.cjs +1 -2
  14. package/adapters/mobile/open-device.sh +2 -2
  15. package/adapters/mobile/reload-app.mjs +4 -4
  16. package/adapters/mobile/reset-app-data.sh +1 -1
  17. package/adapters/mobile/start-console-forwarder.sh +3 -2
  18. package/adapters/mobile/start-metro.sh +17 -12
  19. package/adapters/mobile/wait-for-bridge.cjs +2 -2
  20. package/adapters/shared/harness-source-fingerprint.mjs +13 -8
  21. package/adapters/shared/open-debug.mjs +2 -2
  22. package/adapters/shared/sync-wallet-fixture.sh +8 -5
  23. package/adapters/terminal/cleanup.mjs +2 -1
  24. package/adapters/terminal/inject.mjs +2 -1
  25. package/bin/mm-harness +9 -28
  26. package/dist/adapters/checkout-files.js +16 -0
  27. package/dist/adapters/console-capture.js +14 -1
  28. package/dist/adapters/core/actions.js +4 -3
  29. package/dist/adapters/core/overlay.js +1 -1
  30. package/dist/adapters/core/readiness.js +28 -1
  31. package/dist/adapters/core/run.js +2 -2
  32. package/dist/adapters/core/surface.js +16 -1
  33. package/dist/adapters/extension/browser-pid.js +56 -0
  34. package/dist/adapters/extension/console-capture.js +1 -1
  35. package/dist/adapters/extension/doctor-checks.js +1 -1
  36. package/dist/adapters/extension/ensure-ready.js +5 -4
  37. package/dist/adapters/extension/extension-id.js +1 -1
  38. package/dist/adapters/extension/feature-flags.js +1 -1
  39. package/dist/adapters/extension/fixtures.js +1 -2
  40. package/dist/adapters/extension/launch.js +4 -5
  41. package/dist/adapters/extension/launched-browser.js +1 -2
  42. package/dist/adapters/extension/network-observer.js +1 -1
  43. package/dist/adapters/extension/overlay.js +1 -1
  44. package/dist/adapters/extension/product-config.js +1 -1
  45. package/dist/adapters/extension/readiness.js +1 -1
  46. package/dist/adapters/extension/reload.js +1 -1
  47. package/dist/adapters/extension/run.js +24 -10
  48. package/dist/adapters/extension/runtime-decision.js +2 -1
  49. package/dist/adapters/extension/runtime.js +9 -5
  50. package/dist/adapters/extension/surface.js +15 -2
  51. package/dist/adapters/extension/verify.js +2 -2
  52. package/dist/adapters/harness-freshness.js +2 -1
  53. package/dist/adapters/mobile/android-gfxinfo-performance.js +1 -3
  54. package/dist/adapters/mobile/app-identity.js +10 -0
  55. package/dist/adapters/mobile/doctor-checks.js +1 -1
  56. package/dist/adapters/mobile/fixtures.js +1 -1
  57. package/dist/adapters/mobile/launch.js +27 -28
  58. package/dist/adapters/mobile/lifecycle.js +1 -1
  59. package/dist/adapters/mobile/metro-env.js +9 -59
  60. package/dist/adapters/mobile/performance-observer.js +1 -1
  61. package/dist/adapters/mobile/prepare-target.js +1 -1
  62. package/dist/adapters/mobile/prepare.js +3 -4
  63. package/dist/adapters/mobile/provision.js +1 -1
  64. package/dist/adapters/mobile/readiness.js +1 -1
  65. package/dist/adapters/mobile/recording-target.js +15 -0
  66. package/dist/adapters/mobile/release-artifact-state.js +1 -1
  67. package/dist/adapters/mobile/reload.js +1 -1
  68. package/dist/adapters/mobile/run.js +8 -7
  69. package/dist/adapters/mobile/runtime-decision.js +2 -4
  70. package/dist/adapters/mobile/source-freshness.js +22 -126
  71. package/dist/adapters/mobile/surface.js +26 -3
  72. package/dist/adapters/mobile/ui.js +16 -5
  73. package/dist/adapters/mobile/verify.js +2 -3
  74. package/dist/adapters/performance/cdp-trace.js +1 -1
  75. package/dist/adapters/performance/device-platform.js +1 -1
  76. package/dist/adapters/slot-ports.js +1 -1
  77. package/dist/adapters/surface.js +1 -0
  78. package/dist/adapters/terminal/console-capture.js +1 -1
  79. package/dist/adapters/terminal/launch.js +1 -1
  80. package/dist/adapters/terminal/run.js +25 -2
  81. package/dist/adapters/terminal/surface.js +7 -1
  82. package/dist/adapters.js +8 -4
  83. package/dist/advisor-policy.js +1 -1
  84. package/dist/checkout-view.js +1 -2
  85. package/dist/cli.js +28 -15
  86. package/dist/command-contract.js +1 -26
  87. package/dist/commands/call.js +10 -24
  88. package/dist/commands/check.js +3 -4
  89. package/dist/commands/checklist.js +1 -1
  90. package/dist/commands/completion-candidates.js +2 -10
  91. package/dist/commands/config.js +2 -2
  92. package/dist/commands/core-readiness.js +12 -7
  93. package/dist/commands/debug.js +3 -3
  94. package/dist/commands/device-target.js +5 -5
  95. package/dist/commands/doctor.js +2 -14
  96. package/dist/commands/domain.js +2 -2
  97. package/dist/commands/ensure-ready.js +1 -7
  98. package/dist/commands/fixtures.js +5 -6
  99. package/dist/commands/help.js +3 -4
  100. package/dist/commands/launch/device.js +10 -17
  101. package/dist/commands/launch/extension.js +2 -8
  102. package/dist/commands/launch/mobile.js +1 -1
  103. package/dist/commands/list-executables.js +1 -3
  104. package/dist/commands/logs.js +3 -3
  105. package/dist/commands/manifest.js +1 -12
  106. package/dist/commands/mobile-device-view.js +4 -2
  107. package/dist/commands/overlay.js +110 -0
  108. package/dist/commands/pin.js +1 -1
  109. package/dist/commands/pr-body.js +2 -2
  110. package/dist/commands/prepare.js +4 -9
  111. package/dist/commands/provision.js +3 -12
  112. package/dist/commands/recipe-advice.js +1 -2
  113. package/dist/commands/recipe-quality.js +2 -3
  114. package/dist/commands/resolve-extension.js +1 -7
  115. package/dist/commands/review.js +4 -4
  116. package/dist/commands/run-engine.js +12 -51
  117. package/dist/commands/run.js +4 -25
  118. package/dist/commands/runtime-decision.js +1 -6
  119. package/dist/commands/runtime-health.js +1 -7
  120. package/dist/commands/runtime-launch.js +1 -13
  121. package/dist/commands/self-test.js +2 -6
  122. package/dist/commands/status-watch.js +1 -2
  123. package/dist/commands/status.js +2 -5
  124. package/dist/commands/task-init.js +2 -3
  125. package/dist/commands/tutorial.js +2 -2
  126. package/dist/commands/update.js +1 -1
  127. package/dist/completions-cache.js +1 -1
  128. package/dist/console-classifier.js +19 -0
  129. package/dist/doctor.js +2 -3
  130. package/dist/funding-execution-context.js +15 -1
  131. package/dist/host.js +32 -0
  132. package/dist/index.js +1 -6
  133. package/dist/live-tsx.js +49 -0
  134. package/dist/mm-harness-cli.js +2 -4
  135. package/dist/network-observation.js +4 -4
  136. package/dist/paths.js +34 -64
  137. package/dist/performance-observation.js +2 -2
  138. package/dist/progress.js +1 -1
  139. package/dist/recipe-assistance-context.js +1 -3
  140. package/dist/recipe-security.js +2 -59
  141. package/dist/review/knowledge.js +2 -2
  142. package/dist/runner.js +5 -3
  143. package/dist/runtime-context.js +1 -1
  144. package/dist/task-view.js +2 -3
  145. package/docs/CONTRIBUTING.md +1 -1
  146. package/docs/cli-contract.md +2 -2
  147. package/docs/feature-guard.md +90 -0
  148. package/library/README.md +3 -1
  149. package/library/actions/core/perps/_controller.mjs +153 -130
  150. package/library/actions/core/perps/quote_fees.mjs +58 -0
  151. package/library/actions/core/wallet/_fixture-accounts.mjs +69 -0
  152. package/library/actions/core/wallet/list_accounts.mjs +14 -57
  153. package/library/actions/extension/feature_flags/state.mjs +1 -1
  154. package/library/actions/extension/platform/cdp.mjs +2 -8
  155. package/library/actions/harness-exports.mjs +1 -6
  156. package/library/actions/mobile/app/network-control.mjs +6 -8
  157. package/library/actions/mobile/perps/prepare_local_snapshot_endpoint.mjs +1 -1
  158. package/library/actions/mobile/platform/bridge.mjs +8 -8
  159. package/library/actions/mobile/platform/native-session-name.mjs +21 -1
  160. package/library/actions/mobile/platform/native-session.mjs +3 -4
  161. package/library/actions/mobile/platform/observe-ui.mjs +12 -6
  162. package/library/actions/mobile/ui/native-navigation.mjs +4 -3
  163. package/library/actions/mobile/wallet/native-ui.mjs +3 -2
  164. package/library/actions/shared/analytics/_adapter.mjs +1 -1
  165. package/library/actions/shared/console-findings.mjs +1 -1
  166. package/library/actions/terminal/platform/runtime.mjs +2 -1
  167. package/library/manifests/core.action-manifest.json +83 -13
  168. package/package.json +8 -9
  169. package/adapters/extension/lib/slot-title.cjs +0 -292
  170. package/adapters/mobile/bridge-runtime/console-forwarder.cjs +0 -472
  171. package/adapters/mobile/bridge-runtime/lib/bridge-errors.cjs +0 -125
  172. package/adapters/mobile/bridge-runtime/lib/cdp-broker.cjs +0 -1055
  173. package/adapters/mobile/bridge-runtime/lib/cdp-eval.cjs +0 -110
  174. package/adapters/mobile/bridge-runtime/lib/config.cjs +0 -61
  175. package/adapters/mobile/bridge-runtime/lib/console-format.cjs +0 -53
  176. package/adapters/mobile/bridge-runtime/lib/devtools-proxy.cjs +0 -177
  177. package/adapters/mobile/bridge-runtime/lib/issue-capture.cjs +0 -446
  178. package/adapters/mobile/bridge-runtime/lib/match-bridge-target.cjs +0 -84
  179. package/adapters/mobile/bridge-runtime/lib/target-discovery.cjs +0 -403
  180. package/adapters/mobile/bridge-runtime/lib/ws-client.cjs +0 -116
  181. package/adapters/mobile/coalesce-metro-log.cjs +0 -24
  182. package/adapters/mobile/launch-metro.cjs +0 -77
  183. package/adapters/mobile/metro-config.cjs +0 -98
  184. package/adapters/mobile/metro-log-generation.cjs +0 -106
  185. package/dist/adapters/mobile/frame-metrics.js +0 -118
  186. package/dist/adapters/mobile/video-recorder.js +0 -289
  187. package/dist/artifact-files.js +0 -92
  188. package/dist/checkout-lock.js +0 -149
  189. package/dist/cli-color.js +0 -98
  190. package/dist/command-journal.js +0 -308
  191. package/dist/commands/last.js +0 -60
  192. package/dist/commands/launch/index.js +0 -109
  193. package/dist/commands/parse-args.js +0 -279
  194. package/dist/commands/reload.js +0 -41
  195. package/dist/commands/run-report.js +0 -241
  196. package/dist/commands/shared.js +0 -323
  197. package/dist/commands/stop.js +0 -60
  198. package/dist/devices.js +0 -100
  199. package/dist/execution-provenance.js +0 -332
  200. package/dist/harness.js +0 -451
  201. package/dist/heal-bounds.js +0 -137
  202. package/dist/json-stream.js +0 -60
  203. package/dist/leaf-invoke.js +0 -19
  204. package/dist/library-provenance.js +0 -33
  205. package/dist/live-adapter-contract.js +0 -380
  206. package/dist/recording-target.js +0 -120
  207. package/dist/run-diagnostics.js +0 -364
  208. package/dist/run-recording.js +0 -481
  209. package/dist/runtime-proof.js +0 -90
  210. package/library/actions/mobile/platform/tool-paths.mjs +0 -123
@@ -1,60 +0,0 @@
1
- import { readCommandJournal } from "../command-journal.js";
2
- import { EXIT } from "./shared.js";
3
- import {
4
- optionFlag,
5
- optionString,
6
- shellQuote,
7
- targetPath
8
- } from "./parse-args.js";
9
- async function handleLast({ options }) {
10
- const target = targetPath(options);
11
- const { file, record } = readCommandJournal(target, optionString(options, "runtimeDir"));
12
- const json = optionFlag(options, "json");
13
- if (!record) {
14
- const message = `no resumability journal exists for ${target}`;
15
- const userAction = "run a proof or runtime command in this checkout, then re-run mm-harness last --json";
16
- if (json) {
17
- console.log(JSON.stringify({
18
- schemaVersion: 1,
19
- command: "last",
20
- target,
21
- journalPath: file,
22
- status: "fail",
23
- exitCode: EXIT.runtime,
24
- error: { code: "LAST_NOT_FOUND", message, userAction }
25
- }, null, 2));
26
- } else {
27
- console.error(`\u2717 mm-harness last: ${message}
28
- Next: ${userAction}`);
29
- }
30
- return EXIT.runtime;
31
- }
32
- if (json) {
33
- console.log(JSON.stringify({
34
- schemaVersion: 1,
35
- command: "last",
36
- target,
37
- journalPath: file,
38
- status: "pass",
39
- exitCode: EXIT.ok,
40
- last: record
41
- }, null, 2));
42
- } else {
43
- const end = record.finishedAt ?? "still running or interrupted";
44
- console.log(`${record.verdict.toUpperCase()} ${record.command} (exit ${record.exitCode ?? "pending"})`);
45
- console.log(`command: mm-harness ${record.command}${record.args.length > 0 ? ` ${record.args.map(shellQuote).join(" ")}` : ""}`);
46
- console.log(`started: ${record.startedAt}`);
47
- console.log(`finished: ${end}`);
48
- if (record.evidencePaths.length > 0) {
49
- console.log("evidence:");
50
- for (const evidence of record.evidencePaths) console.log(` ${evidence}`);
51
- } else {
52
- console.log("evidence: none recorded");
53
- }
54
- console.log(`journal: ${file}`);
55
- }
56
- return EXIT.ok;
57
- }
58
- export {
59
- handleLast
60
- };
@@ -1,109 +0,0 @@
1
- import fs from "node:fs";
2
- import { getAdapterSurface } from "../../adapters/surface.js";
3
- import {
4
- ADAPTER_DETECT_NEXT,
5
- checkoutBusyOut,
6
- EXIT,
7
- flag,
8
- parseFlags,
9
- resolveAdapter,
10
- str,
11
- targetOf,
12
- usageOut
13
- } from "../shared.js";
14
- import { parseHeal } from "../../heal-bounds.js";
15
- import { acquireCheckoutLock } from "../../checkout-lock.js";
16
- import { JsonStreamWriter } from "../../json-stream.js";
17
- import { shellQuote } from "./quote.js";
18
- const LAUNCH_BOOLEANS = /* @__PURE__ */ new Set([
19
- "build",
20
- "watch",
21
- "verify",
22
- "sidepanel",
23
- "fullscreen",
24
- "runway",
25
- "clearMetro",
26
- "json",
27
- "jsonStream",
28
- "freshProfile",
29
- "headless",
30
- "headful"
31
- ]);
32
- async function handleLaunch(argv) {
33
- const { options } = parseFlags(argv, LAUNCH_BOOLEANS);
34
- const json = flag(options, "json");
35
- const stream = new JsonStreamWriter("launch", flag(options, "jsonStream"));
36
- const jsonOutput = json && !stream.enabled;
37
- const restoreStdout = stream.isolateStdout();
38
- const target = targetOf(options);
39
- try {
40
- let exitCode;
41
- if (!fs.existsSync(target)) {
42
- exitCode = await handleLaunchLocked(argv, stream);
43
- } else {
44
- const lock = acquireCheckoutLock(target, "launch");
45
- if ("message" in lock) {
46
- const userAction = `wait for the current owner, or inspect ${lock.path} if its process has exited`;
47
- stream.error({ code: "SANDBOX_BUSY", message: lock.message, userAction });
48
- exitCode = checkoutBusyOut(jsonOutput, "launch", lock.message, lock.path);
49
- } else {
50
- try {
51
- exitCode = await handleLaunchLocked(argv, stream);
52
- } finally {
53
- lock.release();
54
- }
55
- }
56
- }
57
- stream.complete(exitCode === EXIT.ok ? "pass" : "fail", exitCode);
58
- return exitCode;
59
- } catch (error) {
60
- const exitCode = error !== null && typeof error === "object" && "exitCode" in error && typeof error.exitCode === "number" ? error.exitCode : EXIT.runtime;
61
- stream.error({
62
- code: exitCode === EXIT.usage ? "CLI_USAGE_ERROR" : "LAUNCH_FAILED",
63
- message: error instanceof Error ? error.message : String(error),
64
- userAction: `mm-harness doctor --target ${shellQuote(target)} --json`
65
- });
66
- stream.complete("fail", exitCode);
67
- throw error;
68
- } finally {
69
- restoreStdout();
70
- }
71
- }
72
- async function handleLaunchLocked(argv, stream) {
73
- const { positional, options } = parseFlags(argv, LAUNCH_BOOLEANS);
74
- const json = flag(options, "json");
75
- const jsonOutput = json && !stream.enabled;
76
- const machine = json || stream.enabled;
77
- const target = targetOf(options);
78
- const heal = parseHeal(options, "auto");
79
- if (typeof heal !== "string") return launchUsage(jsonOutput, stream, heal.error, "use --heal off|infra-only|auto");
80
- const posToken = positional[0];
81
- const mobileTargetToken = posToken === "ios" || posToken === "android" ? posToken : void 0;
82
- const platformFlag = str(options, "platform");
83
- const platformMobileToken = platformFlag === "ios" || platformFlag === "android" ? platformFlag : void 0;
84
- const mobileTarget = mobileTargetToken ?? platformMobileToken;
85
- const adapterHint = mobileTarget ? "mobile" : void 0;
86
- const adapter = resolveAdapter(options, target, adapterHint);
87
- if (!adapter) {
88
- return launchUsage(jsonOutput, stream, `could not detect the MetaMask repo type for ${target}`, ADAPTER_DETECT_NEXT);
89
- }
90
- stream.phase("resolve", { target, adapter, platform: mobileTarget ?? null });
91
- return getAdapterSurface(adapter).launch({
92
- adapter,
93
- target,
94
- options,
95
- mobileTarget,
96
- heal,
97
- jsonOutput,
98
- machine,
99
- stream,
100
- usage: (message, userAction) => launchUsage(jsonOutput, stream, message, userAction)
101
- });
102
- }
103
- function launchUsage(json, stream, message, userAction) {
104
- stream.error({ code: "USAGE", message, userAction });
105
- return usageOut(json, "launch", message, userAction);
106
- }
107
- export {
108
- handleLaunch
109
- };
@@ -1,279 +0,0 @@
1
- import path from "node:path";
2
- import { detectAdapter } from "../harness.js";
3
- import { adapterRegistry } from "../adapters/registry.js";
4
- import { assertAdapter } from "../paths.js";
5
- import { explicitRecipeTrustOptions } from "../recipe-security.js";
6
- import { ADAPTER_DETECT_NEXT } from "./shared.js";
7
- import { EXIT } from "./shared.js";
8
- class CliError extends Error {
9
- exitCode;
10
- constructor(message, exitCode) {
11
- super(message);
12
- this.name = "CliError";
13
- this.exitCode = exitCode;
14
- }
15
- }
16
- function usageError(message) {
17
- return new CliError(message, EXIT.usage);
18
- }
19
- function parseArgs(argv, command) {
20
- const positional = [];
21
- const options = {};
22
- const booleanOptions = /* @__PURE__ */ new Set([
23
- "json",
24
- "jsonStream",
25
- "launchExistingDist",
26
- "startWatch",
27
- "buildLavamoat",
28
- "resetProfile",
29
- "preserveProfile",
30
- "record",
31
- "plan",
32
- "proof",
33
- "list",
34
- "describe",
35
- "raw",
36
- "matrix",
37
- "categories",
38
- "fix",
39
- "force",
40
- "clearMetro",
41
- "resolveOnly",
42
- "expectLive",
43
- "printReady",
44
- "fast",
45
- "allDevices",
46
- "watch",
47
- "help",
48
- "noOpen"
49
- ]);
50
- const repeatableOptions = /* @__PURE__ */ new Set(["library"]);
51
- for (let i = 0; i < argv.length; i += 1) {
52
- const arg = argv[i];
53
- if (!arg.startsWith("--")) {
54
- positional.push(arg);
55
- continue;
56
- }
57
- const body = arg.slice(2);
58
- const equalsIndex = body.indexOf("=");
59
- const rawKey = equalsIndex === -1 ? body : body.slice(0, equalsIndex);
60
- const inlineValue = equalsIndex === -1 ? void 0 : body.slice(equalsIndex + 1);
61
- const key = normalizeOptionKey(rawKey);
62
- if (key === "recordVideo") {
63
- options.recordVideo = parseRecordVideoMode(inlineValue);
64
- continue;
65
- }
66
- if (key === "recordBaseline") {
67
- options.record = true;
68
- continue;
69
- }
70
- if (key === "record") {
71
- if (command === "runtime-decision") {
72
- options.record = true;
73
- continue;
74
- }
75
- options.recordVideo = "full-run";
76
- continue;
77
- }
78
- if (booleanOptions.has(key)) {
79
- options[key] = true;
80
- continue;
81
- }
82
- if (inlineValue !== void 0) {
83
- assignOption(options, key, inlineValue, repeatableOptions);
84
- continue;
85
- }
86
- if (i + 1 >= argv.length) throw usageError(`Missing value for ${arg}`);
87
- assignOption(options, key, argv[i + 1], repeatableOptions);
88
- i += 1;
89
- }
90
- return { positional, options, rawArgv: [...argv] };
91
- }
92
- function assignOption(options, key, value, repeatableOptions) {
93
- if (!repeatableOptions.has(key)) {
94
- options[key] = value;
95
- return;
96
- }
97
- const existing = options[key];
98
- if (existing === void 0) {
99
- options[key] = [value];
100
- return;
101
- }
102
- if (!Array.isArray(existing)) throw usageError(`--${key} has conflicting values.`);
103
- options[key] = [...existing, value];
104
- }
105
- function parseRecipeParamAssignments(values) {
106
- const params = {};
107
- for (const assignment of values) {
108
- const separator = assignment.indexOf("=");
109
- if (separator <= 0) {
110
- throw usageError(`recipe parameter ${JSON.stringify(assignment)} must use key=value.`);
111
- }
112
- const key = assignment.slice(0, separator).trim();
113
- if (!key) throw usageError(`recipe parameter ${JSON.stringify(assignment)} has an empty key.`);
114
- if (Object.hasOwn(params, key)) {
115
- throw usageError(`recipe parameter ${JSON.stringify(key)} was provided more than once.`);
116
- }
117
- const raw = assignment.slice(separator + 1);
118
- let value;
119
- try {
120
- value = JSON.parse(raw);
121
- } catch {
122
- value = raw;
123
- }
124
- Object.defineProperty(params, key, {
125
- value,
126
- enumerable: true,
127
- configurable: true,
128
- writable: true
129
- });
130
- }
131
- return params;
132
- }
133
- function parseRecordVideoMode(value) {
134
- if (value === void 0 || value === "" || value === "true") return "full-run";
135
- if (value === "off" || value === "false") return false;
136
- if (value === "proof-window" || value === "proof_window") {
137
- throw usageError(
138
- "--record-video=proof-window is not supported yet; use --record-video=full-run."
139
- );
140
- }
141
- if (value !== "full-run") {
142
- throw usageError("--record-video must be full-run or off.");
143
- }
144
- return "full-run";
145
- }
146
- function normalizeOptionKey(key) {
147
- return key.replace(/-([a-z])/gu, (_, character) => character.toUpperCase());
148
- }
149
- function optionString(options, key) {
150
- const value = options[key];
151
- if (value === void 0) return void 0;
152
- if (typeof value !== "string") throw usageError(`--${key} requires a value.`);
153
- return value;
154
- }
155
- function optionStrings(options, key) {
156
- const value = options[key];
157
- if (value === void 0) return void 0;
158
- if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
159
- throw usageError(`--${key} requires a value.`);
160
- }
161
- return value;
162
- }
163
- function optionFlag(options, key) {
164
- const value = options[key];
165
- return value === true;
166
- }
167
- function applyRuntimeDirOption(options) {
168
- const runtimeDir = optionString(options, "runtimeDir");
169
- if (runtimeDir) process.env.RECIPE_RUNTIME_DIR = runtimeDir;
170
- }
171
- function applyWatcherPortOption(options) {
172
- const watcherPort = optionString(options, "watcherPort");
173
- if (!watcherPort) return;
174
- process.env.WATCHER_PORT = watcherPort;
175
- process.env.RECIPE_WATCHER_PORT = watcherPort;
176
- process.env.METRO_PORT = watcherPort;
177
- }
178
- function requiredOption(options, key, message) {
179
- const value = optionString(options, key);
180
- if (!value) throw usageError(message);
181
- return value;
182
- }
183
- function adapterUsageError(error) {
184
- if (error instanceof Error && error.message.startsWith("internal:")) return error;
185
- return usageError(error instanceof Error ? error.message : String(error));
186
- }
187
- function adapterOption(options) {
188
- const adapter = optionString(options, "adapter");
189
- try {
190
- assertAdapter(adapter);
191
- } catch (error) {
192
- throw adapterUsageError(error);
193
- }
194
- return adapter;
195
- }
196
- function targetPath(options) {
197
- return path.resolve(optionString(options, "target") ?? process.cwd());
198
- }
199
- function actionManifestPathOption(options, adapter) {
200
- const configured = optionString(options, "actionManifest");
201
- return configured ? path.resolve(configured) : adapterRegistry.get(adapter).actions.manifestPath();
202
- }
203
- function parsePort(value, errorMessage) {
204
- const port = Number(value);
205
- if (!Number.isInteger(port) || port <= 0) throw usageError(errorMessage);
206
- return port;
207
- }
208
- function runtimeOptionsFromCli(options) {
209
- const recordVideo = options.recordVideo;
210
- const hud = optionString(options, "hud");
211
- const trust = explicitRecipeTrustOptions({
212
- sourceTrust: optionString(options, "sourceTrust"),
213
- sourceKind: optionString(options, "sourceKind"),
214
- sourceName: optionString(options, "sourceName"),
215
- sourceDigest: optionString(options, "sourceDigest"),
216
- approvalDigest: optionString(options, "approvePlan")
217
- });
218
- return {
219
- cdpPort: optionString(options, "cdpPort"),
220
- watcherPort: optionString(options, "watcherPort") ?? optionString(options, "metroPort"),
221
- launchExistingDist: optionFlag(options, "launchExistingDist"),
222
- slot: optionString(options, "slot"),
223
- validationRuntimeDir: optionString(options, "validationRuntimeDir"),
224
- recordVideo: recordVideo === "full-run" ? "full-run" : false,
225
- autoHud: hud === "show" ? true : hud === "hide" ? false : void 0,
226
- fundingRequest: optionString(options, "fundingRequest"),
227
- fundingPreflight: optionString(options, "fundingPreflight"),
228
- fundingReleaseProof: optionString(options, "fundingReleaseProof"),
229
- fundingBalanceProof: optionString(options, "fundingBalanceProof"),
230
- ...trust
231
- };
232
- }
233
- function resolveAdapter(options) {
234
- const target = targetPath(options);
235
- const adapterOptionValue = optionString(options, "adapter");
236
- const platformOptionValue = optionString(options, "platform");
237
- const explicit = adapterOptionValue ?? (platformOptionValue === "ios" || platformOptionValue === "android" ? "mobile" : platformOptionValue);
238
- const adapter = explicit ?? detectAdapter(target);
239
- if (!adapter) {
240
- throw usageError(`could not detect the MetaMask repo type for ${target}
241
- Next: ${ADAPTER_DETECT_NEXT}`);
242
- }
243
- try {
244
- assertAdapter(adapter);
245
- } catch (error) {
246
- throw adapterUsageError(error);
247
- }
248
- return { adapter, target };
249
- }
250
- function shellQuote(value) {
251
- return `'${value.replace(/'/gu, `'\\''`)}'`;
252
- }
253
- function shellQuoteArg(value) {
254
- return /^[A-Za-z0-9_./:=@+-]+$/u.test(value) ? value : shellQuote(value);
255
- }
256
- function isRecord(value) {
257
- return typeof value === "object" && value !== null && !Array.isArray(value);
258
- }
259
- export {
260
- CliError,
261
- actionManifestPathOption,
262
- adapterOption,
263
- applyRuntimeDirOption,
264
- applyWatcherPortOption,
265
- isRecord,
266
- optionFlag,
267
- optionString,
268
- optionStrings,
269
- parseArgs,
270
- parsePort,
271
- parseRecipeParamAssignments,
272
- requiredOption,
273
- resolveAdapter,
274
- runtimeOptionsFromCli,
275
- shellQuote,
276
- shellQuoteArg,
277
- targetPath,
278
- usageError
279
- };
@@ -1,41 +0,0 @@
1
- import { getAdapterSurface } from "../adapters/surface.js";
2
- import {
3
- ADAPTER_DETECT_NEXT,
4
- flag,
5
- parseFlags,
6
- resolveAdapter,
7
- targetOf,
8
- usageOut
9
- } from "./shared.js";
10
- const RELOAD_BOOLEANS = /* @__PURE__ */ new Set(["json"]);
11
- async function handleReload(argv) {
12
- const { options } = parseFlags(argv, RELOAD_BOOLEANS);
13
- const json = flag(options, "json");
14
- const target = targetOf(options);
15
- const adapter = resolveAdapter(options, target);
16
- if (!adapter) {
17
- return usageOut(
18
- json,
19
- "reload",
20
- `could not detect the MetaMask repo type for ${target}`,
21
- ADAPTER_DETECT_NEXT
22
- );
23
- }
24
- const surface = getAdapterSurface(adapter);
25
- if (surface.headless) {
26
- return usageOut(
27
- json,
28
- "reload",
29
- `${adapter} is headless; there is no app runtime to reload.`,
30
- `mm-harness run <${adapter}-recipe>`
31
- );
32
- }
33
- if (!surface.reload) {
34
- return usageOut(json, "reload", `reload does not support the ${adapter} adapter.`, surface.hints.launch);
35
- }
36
- surface.resolveSlotPorts(target);
37
- return surface.reload(target, json);
38
- }
39
- export {
40
- handleReload
41
- };