@deeeed/metamask-harness 0.29.1 → 0.29.3

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.29.3 - 2026-08-01
6
+
7
+ ### Fixed
8
+
9
+ - Preserve immutable harness snapshots during runner dependency bootstrap by installing from the repository's pinned Yarn lock without build scripts or inherited product Yarn settings, while recognizing dependencies hoisted by `npx`.
10
+
11
+ ## 0.29.2 - 2026-08-01
12
+
13
+ ### Changed
14
+
15
+ - Upgrade `@farmslot/recipe-harness` to 0.11.1 so iOS lifecycle terminate and restart remain idempotent when Simulator reports that it found nothing to terminate.
16
+
5
17
  ## 0.29.1 - 2026-08-01
6
18
 
7
19
  ### Added
@@ -414,7 +414,7 @@
414
414
  "id": "lib/ensure-runner-deps",
415
415
  "entry": "adapters/shared/ensure-runner-deps.sh",
416
416
  "kind": "lib",
417
- "purpose": "Idempotent install of runner npm deps (@farmslot/recipe-harness) for cloned checkouts with no node_modules; uses npm so parent product .yarnrc.yml does not block install.",
417
+ "purpose": "Idempotent install of runner dependencies from its immutable Yarn lock; isolates runner settings so parent product .yarnrc.yml does not block install.",
418
418
  "inputs": "ensure-runner-deps.sh [RUNNER_DIR]; env FARMSLOT_ROOT / METAMASK_RUNNER_PROTOCOL_ROOT optional local link target",
419
419
  "outputs": "installed node_modules in RUNNER_DIR; exit 0 when deps ready"
420
420
  },
@@ -1,10 +1,9 @@
1
1
  #!/usr/bin/env bash
2
- # ensure-runner-deps.sh — idempotent install of runner npm dependencies.
2
+ # ensure-runner-deps.sh — idempotent install of runner dependencies.
3
3
  #
4
4
  # Source checkout runs TypeScript via Node/tsx and imports @farmslot/recipe-harness.
5
- # Cloned runner checkouts under product temp/ often have no node_modules; parent
6
- # product repos may ship a .yarnrc.yml that the runner's pinned Yarn rejects, so
7
- # use npm here (not yarn install).
5
+ # Cloned runner checkouts under product temp/ often have no node_modules, so use
6
+ # the runner's pinned Yarn release and immutable lockfile.
8
7
  #
9
8
  # Usage: ensure-runner-deps.sh [RUNNER_DIR]
10
9
  # Env: FARMSLOT_ROOT / METAMASK_RUNNER_PROTOCOL_ROOT — optional local link target
@@ -73,22 +72,31 @@ if [ -n "$PROTOCOL_ROOT" ] && [ -f "$RUNNER_DIR/scripts/link-local-farmslot.mjs"
73
72
  fi
74
73
  fi
75
74
 
76
- echo "mm-harness: installing runner dependencies via npm in $RUNNER_DIR" >&2
75
+ echo "mm-harness: installing runner dependencies via Yarn in $RUNNER_DIR" >&2
77
76
  (
78
77
  cd "$RUNNER_DIR"
79
78
  umask 022
80
- npm_config_cache="${MM_HARNESS_NPM_CACHE:-${TMPDIR:-/tmp}/mm-harness-npm-cache-${UID:-$(id -u)}}" \
81
- npm install --ignore-scripts >&2
79
+ COREPACK_BIN="$(type -P corepack || true)"
80
+ if [ -z "$COREPACK_BIN" ]; then
81
+ echo "mm-harness: Corepack is required to install runner dependencies" >&2
82
+ echo "Next: npm install -g corepack && corepack enable" >&2
83
+ exit 1
84
+ fi
85
+ YARN_RC_FILENAME=.mm-harness-runner.yml \
86
+ YARN_NODE_LINKER=node-modules \
87
+ YARN_ENABLE_GLOBAL_CACHE=false \
88
+ YARN_CACHE_FOLDER="$RUNNER_DIR/.yarn/cache" \
89
+ "$COREPACK_BIN" yarn install --immutable --mode=skip-build >&2
82
90
  )
83
91
 
84
- # npm may replace the local protocol links with registry packages. Restore the
92
+ # Yarn may replace the local protocol links with registry packages. Restore the
85
93
  # explicit co-development override after the complete dependency tree exists.
86
94
  if [ -n "$PROTOCOL_ROOT" ] && [ -f "$RUNNER_DIR/scripts/link-local-farmslot.mjs" ]; then
87
95
  FARMSLOT_ROOT="$PROTOCOL_ROOT" node "$RUNNER_DIR/scripts/link-local-farmslot.mjs" >&2
88
96
  fi
89
97
 
90
98
  if ! deps_ready; then
91
- echo "mm-harness: runner dependencies still missing after npm install: $RUNNER_DIR" >&2
99
+ echo "mm-harness: runner dependencies still missing after Yarn install: $RUNNER_DIR" >&2
92
100
  exit 1
93
101
  fi
94
102
 
@@ -13,10 +13,17 @@ if (!runnerDir) process.exit(1);
13
13
  const pkg = JSON.parse(
14
14
  fs.readFileSync(path.join(runnerDir, 'package.json'), 'utf8'),
15
15
  );
16
+ const requireFromRunner = createRequire(path.join(runnerDir, 'package.json'));
17
+ const installedPackageSuffix = path.join(
18
+ 'node_modules',
19
+ ...pkg.name.split('/'),
20
+ );
21
+ const acceptsHoistedDependencies = path
22
+ .resolve(runnerDir)
23
+ .endsWith(`${path.sep}${installedPackageSuffix}`);
16
24
 
17
25
  let dependencyVersionSatisfies;
18
26
  try {
19
- const requireFromRunner = createRequire(path.join(runnerDir, 'package.json'));
20
27
  const helperPath = requireFromRunner.resolve(
21
28
  '@farmslot/recipe-harness/runtime/deps-readiness',
22
29
  );
@@ -52,17 +59,29 @@ function isOverrideLink(packageDir) {
52
59
  }
53
60
  }
54
61
 
62
+ function resolveInstalledPackage(name) {
63
+ const moduleDirs = acceptsHoistedDependencies
64
+ ? (requireFromRunner.resolve.paths(name) ?? [])
65
+ : [path.join(runnerDir, 'node_modules')];
66
+ for (const moduleDir of moduleDirs) {
67
+ const packageDir = path.join(moduleDir, ...name.split('/'));
68
+ const installedPath = path.join(packageDir, 'package.json');
69
+ if (fs.existsSync(installedPath)) {
70
+ return {
71
+ packageDir,
72
+ installed: JSON.parse(fs.readFileSync(installedPath, 'utf8')),
73
+ };
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+
55
79
  const invalid = Object.entries(pkg.dependencies ?? {}).filter(
56
80
  ([name, request]) => {
57
- const packageDir = path.join(
58
- runnerDir,
59
- 'node_modules',
60
- ...name.split('/'),
61
- );
62
- const installedPath = path.join(packageDir, 'package.json');
63
- if (!fs.existsSync(installedPath)) return true;
64
- if (isOverrideLink(packageDir)) return false;
65
- const installed = JSON.parse(fs.readFileSync(installedPath, 'utf8'));
81
+ const resolved = resolveInstalledPackage(name);
82
+ if (!resolved) return true;
83
+ if (isOverrideLink(resolved.packageDir)) return false;
84
+ const { installed } = resolved;
66
85
  return !dependencyVersionSatisfies(installed.version, request);
67
86
  },
68
87
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deeeed/metamask-harness",
3
- "version": "0.29.1",
3
+ "version": "0.29.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mm-harness": "bin/mm-harness"
@@ -23,7 +23,7 @@
23
23
  "@farmslot/agent-runtime": "^0.5.0",
24
24
  "@farmslot/handoff": "^0.3.1",
25
25
  "@farmslot/protocol": "^0.15.0",
26
- "@farmslot/recipe-harness": "^0.11.0",
26
+ "@farmslot/recipe-harness": "^0.11.1",
27
27
  "commander": "^12.0.0",
28
28
  "es-module-lexer": "2.3.1",
29
29
  "esbuild": "0.28.1",