@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.
Files changed (252) hide show
  1. package/CHANGELOG.md +73 -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 +16 -64
  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/adapters/terminal/launch.mjs +17 -13
  26. package/adapters/terminal/lib/mainnet-guard.mjs +9 -0
  27. package/adapters/terminal/lib/readiness.mjs +20 -12
  28. package/adapters/terminal/policy.mjs +35 -0
  29. package/adapters/terminal/verify.mjs +10 -3
  30. package/adapters/terminal/wallet-host.mjs +43 -225
  31. package/bin/mm-harness +9 -28
  32. package/dist/adapters/checkout-files.js +16 -0
  33. package/dist/adapters/console-capture.js +14 -1
  34. package/dist/adapters/core/actions.js +8 -4
  35. package/dist/adapters/core/overlay.js +1 -1
  36. package/dist/adapters/core/readiness.js +28 -1
  37. package/dist/adapters/core/run.js +2 -2
  38. package/dist/adapters/core/surface.js +16 -1
  39. package/dist/adapters/extension/actions.js +6 -2
  40. package/dist/adapters/extension/browser-pid.js +56 -0
  41. package/dist/adapters/extension/console-capture.js +1 -1
  42. package/dist/adapters/extension/doctor-checks.js +1 -1
  43. package/dist/adapters/extension/ensure-ready.js +5 -4
  44. package/dist/adapters/extension/extension-id.js +1 -1
  45. package/dist/adapters/extension/feature-flags.js +1 -1
  46. package/dist/adapters/extension/fixtures.js +1 -2
  47. package/dist/adapters/extension/launch.js +4 -5
  48. package/dist/adapters/extension/launched-browser.js +1 -2
  49. package/dist/adapters/extension/network-observer.js +14 -1
  50. package/dist/adapters/extension/overlay.js +1 -1
  51. package/dist/adapters/extension/product-config.js +1 -1
  52. package/dist/adapters/extension/readiness.js +1 -1
  53. package/dist/adapters/extension/reload.js +1 -1
  54. package/dist/adapters/extension/run.js +135 -14
  55. package/dist/adapters/extension/runtime-decision.js +2 -1
  56. package/dist/adapters/extension/runtime.js +9 -5
  57. package/dist/adapters/extension/surface.js +15 -2
  58. package/dist/adapters/extension/verify.js +2 -2
  59. package/dist/adapters/harness-freshness.js +2 -1
  60. package/dist/adapters/mobile/actions.js +4 -1
  61. package/dist/adapters/mobile/android-gfxinfo-performance.js +1 -3
  62. package/dist/adapters/mobile/app-identity.js +10 -0
  63. package/dist/adapters/mobile/doctor-checks.js +1 -1
  64. package/dist/adapters/mobile/fixtures.js +1 -1
  65. package/dist/adapters/mobile/launch.js +27 -28
  66. package/dist/adapters/mobile/lifecycle.js +1 -1
  67. package/dist/adapters/mobile/metro-env.js +9 -59
  68. package/dist/adapters/mobile/network-observer.js +68 -0
  69. package/dist/adapters/mobile/performance-observer.js +2 -4
  70. package/dist/adapters/mobile/prepare-target.js +1 -1
  71. package/dist/adapters/mobile/prepare.js +3 -4
  72. package/dist/adapters/mobile/provision.js +1 -1
  73. package/dist/adapters/mobile/readiness.js +1 -1
  74. package/dist/adapters/mobile/recording-target.js +15 -0
  75. package/dist/adapters/mobile/release-artifact-state.js +1 -1
  76. package/dist/adapters/mobile/reload.js +1 -1
  77. package/dist/adapters/mobile/run.js +39 -15
  78. package/dist/adapters/mobile/runtime-decision.js +2 -4
  79. package/dist/adapters/mobile/source-freshness.js +22 -126
  80. package/dist/adapters/mobile/surface.js +26 -3
  81. package/dist/adapters/mobile/ui.js +16 -5
  82. package/dist/adapters/mobile/verify.js +2 -3
  83. package/dist/adapters/performance/cdp-trace.js +1 -1
  84. package/dist/adapters/performance/device-platform.js +1 -1
  85. package/dist/adapters/perps-order-inputs.js +36 -0
  86. package/dist/adapters/proof-failure.js +11 -0
  87. package/dist/adapters/slot-ports.js +1 -1
  88. package/dist/adapters/surface.js +1 -0
  89. package/dist/adapters/terminal/actions.js +4 -1
  90. package/dist/adapters/terminal/console-capture.js +1 -1
  91. package/dist/adapters/terminal/doctor-checks.js +2 -0
  92. package/dist/adapters/terminal/launch.js +4 -1
  93. package/dist/adapters/terminal/overlay.js +8 -1
  94. package/dist/adapters/terminal/run.js +33 -5
  95. package/dist/adapters/terminal/surface.js +9 -1
  96. package/dist/adapters.js +27 -7
  97. package/dist/advisor-policy.js +1 -1
  98. package/dist/checkout-view.js +1 -2
  99. package/dist/cli.js +59 -21
  100. package/dist/command-contract.js +1 -26
  101. package/dist/commands/check.js +33 -10
  102. package/dist/commands/checklist.js +1 -1
  103. package/dist/commands/completion-candidates.js +6 -14
  104. package/dist/commands/config.js +2 -2
  105. package/dist/commands/core-readiness.js +12 -7
  106. package/dist/commands/debug.js +3 -3
  107. package/dist/commands/device-target.js +5 -5
  108. package/dist/commands/doctor.js +2 -14
  109. package/dist/commands/domain.js +2 -2
  110. package/dist/commands/ensure-ready.js +1 -7
  111. package/dist/commands/fixtures.js +5 -6
  112. package/dist/commands/help.js +3 -4
  113. package/dist/commands/launch/device.js +10 -17
  114. package/dist/commands/launch/extension.js +2 -8
  115. package/dist/commands/launch/mobile.js +1 -1
  116. package/dist/commands/logs.js +3 -3
  117. package/dist/commands/mobile-device-view.js +4 -2
  118. package/dist/commands/overlay.js +110 -0
  119. package/dist/commands/pin.js +1 -1
  120. package/dist/commands/pr-body.js +2 -2
  121. package/dist/commands/prepare.js +4 -9
  122. package/dist/commands/provision.js +3 -12
  123. package/dist/commands/recipe-advice.js +1 -2
  124. package/dist/commands/recipe-quality.js +2 -3
  125. package/dist/commands/resolve-extension.js +1 -7
  126. package/dist/commands/review.js +4 -4
  127. package/dist/commands/runtime-decision.js +1 -6
  128. package/dist/commands/runtime-health.js +1 -7
  129. package/dist/commands/runtime-launch.js +1 -13
  130. package/dist/commands/self-test.js +5 -8
  131. package/dist/commands/status-watch.js +1 -2
  132. package/dist/commands/status.js +2 -5
  133. package/dist/commands/task-init.js +2 -3
  134. package/dist/commands/tutorial.js +2 -2
  135. package/dist/commands/update.js +1 -1
  136. package/dist/completions-cache.js +1 -1
  137. package/dist/console-classifier.js +19 -0
  138. package/dist/doctor.js +2 -3
  139. package/dist/engine.js +57 -0
  140. package/dist/funding-execution-context.js +96 -1
  141. package/dist/host.js +32 -0
  142. package/dist/index.js +1 -6
  143. package/dist/live-tsx.js +49 -0
  144. package/dist/mm-harness-cli.js +4 -6
  145. package/dist/paths.js +34 -64
  146. package/dist/performance-observation.js +3 -5
  147. package/dist/progress.js +1 -1
  148. package/dist/recipe-assistance-context.js +6 -9
  149. package/dist/recipe-security.js +2 -59
  150. package/dist/review/knowledge.js +2 -2
  151. package/dist/runner.js +7 -4
  152. package/dist/runtime-context.js +1 -1
  153. package/dist/task-view.js +2 -3
  154. package/docs/CONTRIBUTING.md +5 -3
  155. package/docs/RECIPES.md +31 -3
  156. package/docs/cli-contract.md +2 -2
  157. package/docs/feature-guard.md +90 -0
  158. package/library/README.md +3 -1
  159. package/library/actions/core/perps/_controller.mjs +153 -134
  160. package/library/actions/core/perps/_rewards.mjs +186 -0
  161. package/library/actions/core/perps/close_positions.mjs +1 -1
  162. package/library/actions/core/perps/place_order.mjs +167 -45
  163. package/library/actions/core/perps/quote_fees.mjs +61 -0
  164. package/library/actions/core/wallet/list_accounts.mjs +14 -57
  165. package/library/actions/extension/feature_flags/state.mjs +1 -1
  166. package/library/actions/extension/perps/close_visible_position.mjs +5 -0
  167. package/library/actions/extension/perps/edit_margin.mjs +4 -0
  168. package/library/actions/extension/perps/mutation-receipt.mjs +95 -3
  169. package/library/actions/extension/perps/perps.mjs +320 -3
  170. package/library/actions/extension/perps/place_order.mjs +3 -1
  171. package/library/actions/extension/perps/update_position_tpsl.mjs +4 -0
  172. package/library/actions/extension/platform/cdp.mjs +73 -11
  173. package/library/actions/harness-exports.mjs +1 -6
  174. package/library/actions/mobile/app/network-control.mjs +6 -8
  175. package/library/actions/mobile/perps/perps.mjs +216 -11
  176. package/library/actions/mobile/perps/place_order.mjs +3 -1
  177. package/library/actions/mobile/perps/prepare_local_snapshot_endpoint.mjs +1 -1
  178. package/library/actions/mobile/platform/bridge.mjs +8 -8
  179. package/library/actions/mobile/platform/native-session-name.mjs +21 -1
  180. package/library/actions/mobile/platform/native-session.mjs +3 -4
  181. package/library/actions/mobile/platform/observe-ui.mjs +12 -6
  182. package/library/actions/mobile/ui/native-navigation.mjs +4 -3
  183. package/library/actions/mobile/wallet/native-ui.mjs +3 -2
  184. package/library/actions/shared/analytics/_adapter.mjs +1 -1
  185. package/library/actions/shared/console-findings.mjs +1 -1
  186. package/library/actions/shared/perps/order-policy.mjs +177 -0
  187. package/library/actions/shared/wallet/fixture-accounts.mjs +84 -0
  188. package/library/actions/terminal/app/launch.mjs +3 -2
  189. package/library/actions/terminal/platform/hud.mjs +2 -1
  190. package/library/actions/terminal/platform/page.mjs +2 -1
  191. package/library/actions/terminal/platform/runtime.mjs +2 -1
  192. package/library/actions/terminal/wallet/_signature-log.mjs +40 -161
  193. package/library/actions/terminal/wallet/assert_signatures.mjs +6 -12
  194. package/library/actions/terminal/wallet/read_signatures.mjs +10 -9
  195. package/library/manifests/core.action-manifest.json +87 -13
  196. package/library/manifests/extension.action-manifest.json +4 -0
  197. package/library/manifests/mobile.action-manifest.json +12 -0
  198. package/package.json +8 -9
  199. package/site/assets/help-recipes.json +1 -0
  200. package/adapters/extension/lib/slot-title.cjs +0 -292
  201. package/adapters/mobile/bridge-runtime/console-forwarder.cjs +0 -472
  202. package/adapters/mobile/bridge-runtime/lib/bridge-errors.cjs +0 -125
  203. package/adapters/mobile/bridge-runtime/lib/cdp-broker.cjs +0 -1055
  204. package/adapters/mobile/bridge-runtime/lib/cdp-eval.cjs +0 -110
  205. package/adapters/mobile/bridge-runtime/lib/config.cjs +0 -61
  206. package/adapters/mobile/bridge-runtime/lib/console-format.cjs +0 -53
  207. package/adapters/mobile/bridge-runtime/lib/devtools-proxy.cjs +0 -177
  208. package/adapters/mobile/bridge-runtime/lib/issue-capture.cjs +0 -446
  209. package/adapters/mobile/bridge-runtime/lib/match-bridge-target.cjs +0 -84
  210. package/adapters/mobile/bridge-runtime/lib/target-discovery.cjs +0 -403
  211. package/adapters/mobile/bridge-runtime/lib/ws-client.cjs +0 -116
  212. package/adapters/mobile/coalesce-metro-log.cjs +0 -24
  213. package/adapters/mobile/launch-metro.cjs +0 -77
  214. package/adapters/mobile/metro-config.cjs +0 -98
  215. package/adapters/mobile/metro-log-generation.cjs +0 -106
  216. package/adapters/terminal/lib/origin.mjs +0 -30
  217. package/adapters/terminal/lib/page-script.mjs +0 -246
  218. package/adapters/terminal/lib/strict-wallet.mjs +0 -138
  219. package/dist/adapters/mobile/frame-metrics.js +0 -118
  220. package/dist/adapters/mobile/video-recorder.js +0 -289
  221. package/dist/artifact-files.js +0 -92
  222. package/dist/checkout-lock.js +0 -149
  223. package/dist/cli-color.js +0 -98
  224. package/dist/command-journal.js +0 -308
  225. package/dist/commands/call.js +0 -685
  226. package/dist/commands/last.js +0 -60
  227. package/dist/commands/launch/index.js +0 -109
  228. package/dist/commands/list-executables.js +0 -247
  229. package/dist/commands/manifest.js +0 -488
  230. package/dist/commands/parse-args.js +0 -279
  231. package/dist/commands/reload.js +0 -41
  232. package/dist/commands/run-engine.js +0 -1340
  233. package/dist/commands/run-report.js +0 -241
  234. package/dist/commands/run.js +0 -751
  235. package/dist/commands/shared.js +0 -323
  236. package/dist/commands/stop.js +0 -60
  237. package/dist/devices.js +0 -100
  238. package/dist/discovery.js +0 -15
  239. package/dist/execution-provenance.js +0 -332
  240. package/dist/harness.js +0 -451
  241. package/dist/heal-bounds.js +0 -137
  242. package/dist/json-stream.js +0 -60
  243. package/dist/leaf-invoke.js +0 -19
  244. package/dist/library-provenance.js +0 -33
  245. package/dist/live-adapter-contract.js +0 -380
  246. package/dist/metamask-action-validation.js +0 -68
  247. package/dist/network-observation.js +0 -290
  248. package/dist/recording-target.js +0 -120
  249. package/dist/run-diagnostics.js +0 -364
  250. package/dist/run-recording.js +0 -481
  251. package/dist/runtime-proof.js +0 -90
  252. package/library/actions/mobile/platform/tool-paths.mjs +0 -123
@@ -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
- };
@@ -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
- };