@deeeed/metamask-harness 0.26.2 → 0.26.4

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 CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.26.4 - 2026-07-31
6
+
7
+ ### Fixed
8
+
9
+ - Forward Mobile verify's resolved Metro port into nested recipe runs so an older runtime context cannot redirect live bridge checks to another slot.
10
+
11
+ ## 0.26.3 - 2026-07-31
12
+
13
+ ### Fixed
14
+
15
+ - Stop the verified detached analytics collector with its owning harness runtime instead of leaving an idle process behind.
16
+
5
17
  ## 0.26.2 - 2026-07-31
6
18
 
7
19
  ### Fixed
@@ -321,7 +321,7 @@ JSON
321
321
  cd "$TARGET"
322
322
  device_args=()
323
323
  [ -n "$device_target" ] && device_args=(--device "$device_target")
324
- "$RUNNER_BIN" run "$ARTIFACTS/mobile-status-smoke.recipe.json" --adapter mobile --target "$TARGET" "${device_args[@]}" --artifacts-dir "$ARTIFACTS/runner-status-smoke" --json
324
+ "$RUNNER_BIN" run "$ARTIFACTS/mobile-status-smoke.recipe.json" --adapter mobile --target "$TARGET" "${device_args[@]}" --watcher-port "$port" --artifacts-dir "$ARTIFACTS/runner-status-smoke" --json
325
325
  ) > "$log_path" 2>&1
326
326
  }
327
327
 
@@ -351,6 +351,13 @@ EOF
351
351
  }
352
352
 
353
353
  if [ "$STATIC_ONLY" = false ]; then
354
+ port="$(watcher_port)"
355
+ # Reject a non-numeric port before it reaches runner arguments or the
356
+ # port-holder shell probe.
357
+ case "$port" in
358
+ ""|*[!0-9]*) echo "Refusing mobile verify: resolved watcher port is not numeric: '$port' (check WATCHER_PORT)" >&2; exit 2 ;;
359
+ esac
360
+
354
361
  device_target="$(mobile_device_target)"
355
362
  if [ -z "$device_target" ]; then
356
363
  if [ "$PLATFORM" = "android" ]; then
@@ -376,13 +383,6 @@ if [ "$STATIC_ONLY" = false ]; then
376
383
  add_note "$fixture_message"
377
384
  checks+=("$fixture_check_json")
378
385
 
379
- port="$(watcher_port)"
380
- # Reject a non-numeric port before it is interpolated into a shell command
381
- # (port_holder_json runs `lsof -iTCP:${port}`). The .env path is regex-guarded,
382
- # but the WATCHER_PORT env path is not, so validate here.
383
- case "$port" in
384
- ""|*[!0-9]*) echo "Refusing mobile verify: resolved watcher port is not numeric: '$port' (check WATCHER_PORT)" >&2; exit 2 ;;
385
- esac
386
386
  port_holder_json "$port" > "$ARTIFACTS/logs/port-holder.json"
387
387
 
388
388
  cat > "$ARTIFACTS/mobile-v1-live-smoke.recipe.json" <<'JSON'
@@ -411,7 +411,7 @@ JSON
411
411
  IOS_SIMULATOR="${IOS_SIMULATOR:-$ios_simulator_resolved}" \
412
412
  ADB_SERIAL="${ADB_SERIAL:-$adb_serial_resolved}" \
413
413
  ANDROID_SERIAL="${ANDROID_SERIAL:-$adb_serial_resolved}" \
414
- "$RUNNER_BIN" run "$ARTIFACTS/mobile-v1-live-smoke.recipe.json" --adapter mobile --target "$TARGET" "${device_args[@]}" --artifacts-dir "$ARTIFACTS/runner-live-smoke" --json
414
+ "$RUNNER_BIN" run "$ARTIFACTS/mobile-v1-live-smoke.recipe.json" --adapter mobile --target "$TARGET" "${device_args[@]}" --watcher-port "$port" --artifacts-dir "$ARTIFACTS/runner-live-smoke" --json
415
415
  ) > "$ARTIFACTS/logs/runner-live-smoke.log" 2>&1; then
416
416
  checks+=("{\"name\":\"runner v1 live bridge smoke\",\"status\":\"pass\"}")
417
417
  else
@@ -1,6 +1,7 @@
1
1
  import { color } from "../cli-color.js";
2
2
  import { getAdapterSurface } from "../adapters/surface.js";
3
3
  import { usageOut } from "./shared.js";
4
+ import { stopProjectCollector } from "../../library/actions/shared/analytics/collector.mjs";
4
5
  import {
5
6
  parseArgs,
6
7
  optionFlag,
@@ -23,6 +24,9 @@ async function handleStop(argv) {
23
24
  if (stop.kind === "headless") {
24
25
  return usageOut(json, "stop", stop.message, stop.userAction);
25
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;
26
30
  const next = adapter === "extension" ? `${surface.hints.launch} --target ${shellQuote(target)}` : void 0;
27
31
  const userAction = `mm-harness status --target ${shellQuote(target)} --json`;
28
32
  if (json) {
@@ -34,10 +38,10 @@ async function handleStop(argv) {
34
38
  adapter,
35
39
  target,
36
40
  status: stop.status === 0 ? "pass" : "fail",
37
- ...stop.signalled !== void 0 ? { signalled: stop.signalled } : {},
41
+ ...stop.signalled !== void 0 || collector.stopped ? { signalled } : {},
38
42
  exitCode: stop.status,
39
43
  ...stop.output ? { output: stop.output } : {},
40
- ...stop.status === 0 ? next ? { next } : {} : { error: { code: "DEV_SERVER_STOP_FAILED", message: stop.summary, userAction } }
44
+ ...stop.status === 0 ? next ? { next } : {} : { error: { code: "DEV_SERVER_STOP_FAILED", message: summary, userAction } }
41
45
  },
42
46
  null,
43
47
  2
@@ -46,7 +50,7 @@ async function handleStop(argv) {
46
50
  } else {
47
51
  if (stop.output) process.stderr.write(`${stop.output}
48
52
  `);
49
- console.error(`${color(stop.status === 0 ? "ok" : "err", stop.status === 0 ? "\u2713" : "\u2717")} ${stop.summary}`);
53
+ console.error(`${color(stop.status === 0 ? "ok" : "err", stop.status === 0 ? "\u2713" : "\u2717")} ${summary}`);
50
54
  if (stop.status !== 0 || next) console.error(` Next: ${stop.status === 0 ? next : userAction}`);
51
55
  }
52
56
  return stop.status;
@@ -268,6 +268,22 @@ async function stopCollector(state) {
268
268
  return true;
269
269
  }
270
270
 
271
+ export async function stopProjectCollector(projectRoot) {
272
+ const { stateFile } = collectorPaths(projectRoot);
273
+ const state = await readState(stateFile);
274
+ if (!state) return { stopped: false, pid: null };
275
+
276
+ const stopped = await stopCollector(state);
277
+ if (stopped || !pidAlive(state.pid)) {
278
+ try {
279
+ await unlink(stateFile);
280
+ } catch (error) {
281
+ if (error?.code !== 'ENOENT') throw error;
282
+ }
283
+ }
284
+ return { stopped, pid: stopped ? state.pid : null };
285
+ }
286
+
271
287
  async function stopSpawnedCollector(pid) {
272
288
  if (!pidAlive(pid)) return;
273
289
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deeeed/metamask-harness",
3
- "version": "0.26.2",
3
+ "version": "0.26.4",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mm-harness": "bin/mm-harness"