@deeeed/metamask-harness 0.78.0 → 0.79.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 CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.79.0 - 2026-10-05
6
+
7
+ ### Changed
8
+
9
+ - Depend on `@farmslot/recipe-runner` 0.23.0 (renamed from `@farmslot/recipe-harness`), `@farmslot/adapter-sdk` 0.1.0, `@farmslot/recipe-cli` 0.2.0 and `@farmslot/expo-recipe` 0.14.0. The platform surfaces are written with the SDK's `defineAdapter`, the registry is the SDK's `createAdapterRegistry`, and `AdapterSurface` extends the SDK's `PlatformAdapter`; its id field is now `id` (was `adapter`). MetaMask-only members (Runway provisioning, launch, readiness, fixtures, prepare, debug, runtime-decision, run hooks, observation, the perps action flags) stay on `AdapterSurface`.
10
+ - `--json` output names the runner `@farmslot/recipe-runner`: `doctor`'s `runner.harnessPackage` and the run provenance `harness.name`. Nothing else in the goldens changes.
11
+ - Local co-development needs a Farmslot checkout with `packages/recipe-runner`: auto-discovery skips older checkouts, and an explicit `METAMASK_RUNNER_PROTOCOL_ROOT` or `.farmslot-root` pointing at one fails when loading the runner.
12
+
5
13
  ## 0.78.0 - 2026-10-05
6
14
 
7
15
  ### Changed
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  # ensure-runner-deps.sh — idempotent install of runner dependencies.
3
3
  #
4
- # Source checkout runs TypeScript via Node/tsx and imports @farmslot/recipe-harness.
4
+ # Source checkout runs TypeScript via Node/tsx and imports @farmslot/recipe-runner.
5
5
  # Cloned runner checkouts under product temp/ often have no node_modules, so use
6
6
  # the runner's pinned Yarn release and immutable lockfile.
7
7
  #
@@ -79,7 +79,7 @@ if [ -L "$RUNNER_DIR/node_modules" ]; then
79
79
  fi
80
80
 
81
81
  if [ -n "$PROTOCOL_ROOT" ] && [ -f "$RUNNER_DIR/scripts/link-local-farmslot.mjs" ]; then
82
- if [ -f "$PROTOCOL_ROOT/packages/recipe-harness/package.json" ]; then
82
+ if [ -f "$PROTOCOL_ROOT/packages/recipe-runner/package.json" ]; then
83
83
  FARMSLOT_ROOT="$(cd "$PROTOCOL_ROOT" && pwd -P)" \
84
84
  node "$RUNNER_DIR/scripts/link-local-farmslot.mjs" >&2 || true
85
85
  if deps_ready; then
@@ -25,7 +25,7 @@ const acceptsHoistedDependencies = path
25
25
  let dependencyVersionSatisfies;
26
26
  try {
27
27
  const helperPath = requireFromRunner.resolve(
28
- '@farmslot/recipe-harness/runtime/deps-readiness',
28
+ '@farmslot/recipe-runner/runtime/deps-readiness',
29
29
  );
30
30
  ({ dependencyVersionSatisfies } = await import(pathToFileURL(helperPath).href));
31
31
  if (typeof dependencyVersionSatisfies !== 'function') process.exit(1);
@@ -1,6 +1,6 @@
1
1
  // Minimal browser-level Chrome DevTools Protocol client with flattened target
2
2
  // sessions, for the long-running terminal wallet host. Page-level UI actions use
3
- // @farmslot/recipe-harness/runtime/cdp instead.
3
+ // @farmslot/recipe-runner/runtime/cdp instead.
4
4
 
5
5
  import WebSocket from 'ws';
6
6
 
package/bin/mm-harness CHANGED
@@ -95,11 +95,11 @@ find_protocol_root() {
95
95
  local dir
96
96
  dir="$(cd "$start" && pwd -P)"
97
97
  while [ "$dir" != "/" ]; do
98
- if [ -f "$dir/packages/recipe-harness/package.json" ] && [ -f "$dir/packages/protocol/package.json" ]; then
98
+ if [ -f "$dir/packages/recipe-runner/package.json" ] && [ -f "$dir/packages/protocol/package.json" ]; then
99
99
  printf '%s\n' "$dir"
100
100
  return 0
101
101
  fi
102
- if [ -f "$dir/farmslot/packages/recipe-harness/package.json" ] && [ -f "$dir/farmslot/packages/protocol/package.json" ]; then
102
+ if [ -f "$dir/farmslot/packages/recipe-runner/package.json" ] && [ -f "$dir/farmslot/packages/protocol/package.json" ]; then
103
103
  printf '%s\n' "$dir/farmslot"
104
104
  return 0
105
105
  fi
@@ -13,7 +13,7 @@ async function recipeUsesCoreController(recipe, librarySources) {
13
13
  if (refs.length === 0) return false;
14
14
  const sources = librarySources ?? [];
15
15
  if (sources.length === 0) return false;
16
- const { loadRecipeLibraries } = await import("@farmslot/recipe-harness");
16
+ const { loadRecipeLibraries } = await import("@farmslot/recipe-runner");
17
17
  const recipes = (await loadRecipeLibraries(sources, { adapter: "core" })).recipes;
18
18
  const visited = /* @__PURE__ */ new Set();
19
19
  const visit = (ref) => {
@@ -1,13 +1,15 @@
1
1
  import path from "node:path";
2
- import { depsCheck } from "@farmslot/recipe-harness/runtime/deps-readiness";
2
+ import { depsCheck } from "@farmslot/recipe-runner/runtime/deps-readiness";
3
+ import { defineAdapter } from "@farmslot/adapter-sdk";
3
4
  import { shellQuote } from "../../commands/parse-args.js";
4
5
  import { adapterRegistry } from "../registry.js";
5
6
  import { coreActions } from "./actions.js";
6
7
  import { coreHarness, corePrepare, coreRuntimeContext } from "./overlay.js";
7
8
  import { coreReadiness } from "./readiness.js";
8
9
  import { coreRun } from "./run.js";
9
- const coreSurface = {
10
- adapter: "core",
10
+ const coreSurface = defineAdapter({
11
+ id: "core",
12
+ sdkVersion: 1,
11
13
  headless: true,
12
14
  resolveSlotPorts() {
13
15
  },
@@ -67,7 +69,7 @@ const coreSurface = {
67
69
  fixtures: { operations: ["init", "sync", "set"] },
68
70
  prepare: corePrepare,
69
71
  run: coreRun
70
- };
72
+ });
71
73
  adapterRegistry.register(coreSurface);
72
74
  export {
73
75
  coreSurface
@@ -6,7 +6,7 @@ import { extensionTreeSha256 } from "./artifact-integrity.js";
6
6
  import {
7
7
  depsCheck,
8
8
  INSTALL_MARKERS
9
- } from "@farmslot/recipe-harness/runtime/deps-readiness";
9
+ } from "@farmslot/recipe-runner/runtime/deps-readiness";
10
10
  import { recipeHarnessPath, recipeRuntimeDir, recipeWatchLogCandidates } from "../../paths.js";
11
11
  const WEBPACK_DIRECT_INPUTS = ["package.json", "yarn.lock", ".yarnrc.yml", ".tool-versions"];
12
12
  const WEBPACK_RECURSIVE_INPUTS = ["development/webpack"];
@@ -1,5 +1,6 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import path from "node:path";
3
+ import { defineAdapter } from "@farmslot/adapter-sdk";
3
4
  import { recipeRuntimePath, runnerDir } from "../../paths.js";
4
5
  import { shellQuote } from "../../commands/parse-args.js";
5
6
  import {
@@ -24,8 +25,9 @@ function extensionRuntimeNextAction(reasonCode, target) {
24
25
  if (reasonCode === "rpc-execution-failed") return `mm-harness logs --target ${resolved} --full`;
25
26
  return reasonCode === "deps-missing" || reasonCode === "deps-stale" ? `cd ${resolved} && yarn install --immutable` : `mm-harness launch --adapter extension --target ${resolved}`;
26
27
  }
27
- const extensionSurface = {
28
- adapter: "extension",
28
+ const extensionSurface = defineAdapter({
29
+ id: "extension",
30
+ sdkVersion: 1,
29
31
  headless: false,
30
32
  resolveSlotPorts(target) {
31
33
  resolveExtensionSlotPorts(target);
@@ -135,7 +137,7 @@ const extensionSurface = {
135
137
  recording: extensionRecording,
136
138
  diagnostics: extensionDiagnostics,
137
139
  observation: extensionObservation
138
- };
140
+ });
139
141
  adapterRegistry.register(extensionSurface);
140
142
  export {
141
143
  extensionRuntimeNextAction,
@@ -1,6 +1,6 @@
1
1
  import { execFileSync } from "node:child_process";
2
2
  import path from "node:path";
3
- import { recordDepsBaseline } from "@farmslot/recipe-harness/runtime/deps-readiness";
3
+ import { recordDepsBaseline } from "@farmslot/recipe-runner/runtime/deps-readiness";
4
4
  import { resolveAndExportMobileToolPaths } from "../../../library/actions/mobile/platform/tool-paths.mjs";
5
5
  import { EXIT, spawnScriptStreaming } from "../../commands/shared.js";
6
6
  import { shellQuote } from "../../commands/parse-args.js";
@@ -80,7 +80,7 @@ const mobileRecording = {
80
80
  if (!androidSerial && !iosSimulator) return void 0;
81
81
  const { createAndroidVideoRecorder, createIosSimulatorVideoRecorder } = await import("./video-recorder.js");
82
82
  if (androidSerial) {
83
- const { createAndroidMirrorVideoRecorder } = await import("@farmslot/recipe-harness");
83
+ const { createAndroidMirrorVideoRecorder } = await import("@farmslot/recipe-runner");
84
84
  return createAndroidMirrorVideoRecorder({ serial: androidSerial, fallback: createAndroidVideoRecorder(androidSerial) });
85
85
  }
86
86
  return createIosSimulatorVideoRecorder(iosSimulator);
@@ -5,12 +5,12 @@ import path from "node:path";
5
5
  import {
6
6
  depsCheck,
7
7
  recordDepsBaseline
8
- } from "@farmslot/recipe-harness/runtime/deps-readiness";
8
+ } from "@farmslot/recipe-runner/runtime/deps-readiness";
9
9
  import {
10
10
  analyzeBundleLog,
11
11
  supersededErrorCapture
12
- } from "@farmslot/recipe-harness/runtime/log-analysis";
13
- import { probeMetroPackager } from "@farmslot/recipe-harness/runtime/metro-probe";
12
+ } from "@farmslot/recipe-runner/runtime/log-analysis";
13
+ import { probeMetroPackager } from "@farmslot/recipe-runner/runtime/metro-probe";
14
14
  import { color } from "../../cli-color.js";
15
15
  import { shellQuote } from "../../commands/parse-args.js";
16
16
  import { recipeRuntimePath } from "../../paths.js";
@@ -1,5 +1,6 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import path from "node:path";
3
+ import { defineAdapter } from "@farmslot/adapter-sdk";
3
4
  import { recipeRuntimePath, runnerDir } from "../../paths.js";
4
5
  import { shellQuote } from "../../commands/parse-args.js";
5
6
  import { resolveMobileSlotPorts } from "../slot-ports.js";
@@ -17,8 +18,9 @@ function mobileRuntimeNextAction(reasonCode, target, platform) {
17
18
  const resolved = shellQuote(path.resolve(target));
18
19
  return reasonCode === "deps-missing" || reasonCode === "deps-partial" || reasonCode === "deps-stale" ? `cd ${resolved} && yarn setup` : `mm-harness launch ${platform} --adapter mobile --target ${resolved}`;
19
20
  }
20
- const mobileSurface = {
21
- adapter: "mobile",
21
+ const mobileSurface = defineAdapter({
22
+ id: "mobile",
23
+ sdkVersion: 1,
22
24
  headless: false,
23
25
  resolveSlotPorts(target) {
24
26
  resolveMobileSlotPorts(target);
@@ -104,7 +106,7 @@ const mobileSurface = {
104
106
  diagnostics: mobileDiagnostics,
105
107
  observation: mobileObservation,
106
108
  sourceFingerprint: (root) => mobileSourceFingerprint(root)
107
- };
109
+ });
108
110
  adapterRegistry.register(mobileSurface);
109
111
  export {
110
112
  mobileRuntimeNextAction,
@@ -1,7 +1,7 @@
1
1
  import { spawn, spawnSync } from "node:child_process";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { optionalVideoTiming } from "@farmslot/recipe-harness";
4
+ import { optionalVideoTiming } from "@farmslot/recipe-runner";
5
5
  import {
6
6
  ANDROID_RECORDING_TARGET_PREFIX,
7
7
  IOS_SIMULATOR_RECORDING_TARGET_PREFIX
@@ -1,17 +1,5 @@
1
- const surfaces = /* @__PURE__ */ new Map();
2
- const adapterRegistry = {
3
- register(surface) {
4
- if (surfaces.has(surface.adapter)) throw new Error(`adapter '${surface.adapter}' is already registered`);
5
- surfaces.set(surface.adapter, surface);
6
- },
7
- get(id) {
8
- const surface = surfaces.get(id);
9
- if (!surface) throw new Error(`unknown adapter '${id}' (registered: ${adapterRegistry.list().join(", ")})`);
10
- return surface;
11
- },
12
- has: (id) => surfaces.has(id),
13
- list: () => [...surfaces.keys()]
14
- };
1
+ import { createAdapterRegistry } from "@farmslot/adapter-sdk";
2
+ const adapterRegistry = createAdapterRegistry();
15
3
  export {
16
4
  adapterRegistry
17
5
  };
@@ -1,4 +1,5 @@
1
1
  import path from "node:path";
2
+ import { defineAdapter } from "@farmslot/adapter-sdk";
2
3
  import { shellQuote } from "../../commands/parse-args.js";
3
4
  import fs from "node:fs";
4
5
  import { TERMINAL_CONSOLE_FILES, terminalRuntimeFile } from "./console-capture.js";
@@ -29,8 +30,9 @@ function terminalSignerFor(target) {
29
30
  }
30
31
  return process.env.TERMINAL_SIGNER || "extension";
31
32
  }
32
- const terminalSurface = {
33
- adapter: "terminal",
33
+ const terminalSurface = defineAdapter({
34
+ id: "terminal",
35
+ sdkVersion: 1,
34
36
  headless: false,
35
37
  resolveSlotPorts() {
36
38
  },
@@ -116,7 +118,7 @@ const terminalSurface = {
116
118
  },
117
119
  diagnostics: terminalDiagnostics,
118
120
  observation: terminalObservation
119
- };
121
+ });
120
122
  adapterRegistry.register(terminalSurface);
121
123
  export {
122
124
  terminalAppPort,
@@ -1,4 +1,4 @@
1
- import { ensureRuntimeDirectory, processIdentity } from "@farmslot/recipe-harness/runtime/operation";
1
+ import { ensureRuntimeDirectory, processIdentity } from "@farmslot/recipe-runner/runtime/operation";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { OperationRecord, readOperations, processIdentity, ensureRuntimeDirectory } from "@farmslot/recipe-harness/runtime/operation";
4
+ import { OperationRecord, readOperations, processIdentity, ensureRuntimeDirectory } from "@farmslot/recipe-runner/runtime/operation";
5
5
  import { latestTaskDir } from "@farmslot/agent-runtime";
6
6
  import { recipeRuntimeDir } from "./paths.js";
7
7
  const COMMAND_JOURNAL_FILE = "last-command.json";
@@ -6,7 +6,7 @@ import path from "node:path";
6
6
  import {
7
7
  depsCheck,
8
8
  recordDepsBaseline
9
- } from "@farmslot/recipe-harness/runtime/deps-readiness";
9
+ } from "@farmslot/recipe-runner/runtime/deps-readiness";
10
10
  import { colorHumanMessage } from "../../cli-color.js";
11
11
  import {
12
12
  importRecipeHarnessRuntimeCdp,
@@ -1,7 +1,7 @@
1
1
  import { acquireCheckoutLock, trackCheckoutChild } from "../checkout-lock.js";
2
2
  import { recordCommandStage } from "../command-journal.js";
3
3
  import { spawn } from "node:child_process";
4
- import { OperationOutputTail } from "@farmslot/recipe-harness/runtime/operation";
4
+ import { OperationOutputTail } from "@farmslot/recipe-runner/runtime/operation";
5
5
  import fs from "node:fs";
6
6
  import path from "node:path";
7
7
  import {
@@ -302,7 +302,7 @@ async function handlePrepareLocked(argv) {
302
302
  const json = optionFlag(options, "json");
303
303
  const target = targetPath(options);
304
304
  const surface = resolvePlatform(optionString(options, "platform"), target);
305
- const platform = surface.adapter;
305
+ const platform = surface.id;
306
306
  const artifactsDir = path.resolve(
307
307
  optionString(options, "artifactsDir") ?? path.join(target, recipeRuntimeDir())
308
308
  );
@@ -2,7 +2,7 @@ import { trackCheckoutChild } from "../checkout-lock.js";
2
2
  import { recordCommandOutput, recordCommandStage } from "../command-journal.js";
3
3
  import { spawn, spawnSync } from "node:child_process";
4
4
  import { StringDecoder } from "node:string_decoder";
5
- import { OperationOutputTail } from "@farmslot/recipe-harness/runtime/operation";
5
+ import { OperationOutputTail } from "@farmslot/recipe-runner/runtime/operation";
6
6
  import path from "node:path";
7
7
  import { detectAdapter } from "../harness.js";
8
8
  import { colorHumanMessage } from "../cli-color.js";
package/dist/discovery.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { assessRecipe } from "@farmslot/recipe-cli";
2
2
  import {
3
3
  loadRecipeLibraries
4
- } from "@farmslot/recipe-harness";
4
+ } from "@farmslot/recipe-runner";
5
5
  import { resolveActionManifest } from "./manifest.js";
6
6
  async function runnableLibraryRecipes(adapter, sources) {
7
7
  const resolution = await loadRecipeLibraries(sources, { adapter });
package/dist/doctor.js CHANGED
@@ -224,7 +224,7 @@ function runnerProvenance(actionManifestPath) {
224
224
  invokedPath,
225
225
  executablePath,
226
226
  actionManifestPath,
227
- harnessPackage: "@farmslot/recipe-harness"
227
+ harnessPackage: "@farmslot/recipe-runner"
228
228
  };
229
229
  }
230
230
  function readJsonObject(file) {
package/dist/harness.js CHANGED
@@ -41,7 +41,7 @@ function failureHint(surface, action) {
41
41
  const restart = surface.harness.restart;
42
42
  if (!restart) {
43
43
  if (action === "verify") {
44
- return `Install the ${surface.adapter} harness first: mm-harness install --platform ${surface.adapter}`;
44
+ return `Install the ${surface.id} harness first: mm-harness install --platform ${surface.id}`;
45
45
  }
46
46
  return "Read the error above for the specific cause, then re-run this command.";
47
47
  }
@@ -192,7 +192,7 @@ function installedRunnerSource(target, adapter) {
192
192
  function resolveHarnessDispatch(surface, action, target) {
193
193
  if (action === "verify") return surface.harness.verify(target);
194
194
  const leaf = action === "install" ? surface.harness.install : surface.harness.cleanup;
195
- const base = action === "cleanup" && surface.harness.cleanup.fromInstalledRunner ? installedRunnerSource(target, surface.adapter) ?? runnerDir : runnerDir;
195
+ const base = action === "cleanup" && surface.harness.cleanup.fromInstalledRunner ? installedRunnerSource(target, surface.id) ?? runnerDir : runnerDir;
196
196
  const entry = resolveEntry(base, [leaf.entry, leaf.fallback], "file");
197
197
  return leaf.node ? { command: process.execPath, prefixArgs: [entry] } : { command: entry, prefixArgs: [] };
198
198
  }
@@ -330,7 +330,7 @@ async function handleHarness(argv) {
330
330
  }
331
331
  function reportHarnessOutcome(action, surface, target, exitCode, autoDetected, json, quiet, start) {
332
332
  const seconds = ((Date.now() - start) / 1e3).toFixed(1);
333
- const adapter = surface.adapter;
333
+ const adapter = surface.id;
334
334
  if (quiet) {
335
335
  return exitCode;
336
336
  } else if (json) {
package/dist/paths.js CHANGED
@@ -86,7 +86,7 @@ function findProtocolRoot(start) {
86
86
  return void 0;
87
87
  }
88
88
  function isProtocolRoot(candidate) {
89
- return fs.existsSync(path.join(candidate, "packages/recipe-harness/package.json")) && fs.existsSync(path.join(candidate, "packages/protocol/package.json"));
89
+ return fs.existsSync(path.join(candidate, "packages/recipe-runner/package.json")) && fs.existsSync(path.join(candidate, "packages/protocol/package.json"));
90
90
  }
91
91
  function assertAdapter(adapter) {
92
92
  const ids = adapterRegistry.list();
@@ -110,32 +110,32 @@ function readJson(file) {
110
110
  }
111
111
  async function importRecipeHarness() {
112
112
  return importProtocolPackage(
113
- "@farmslot/recipe-harness",
114
- "packages/recipe-harness/src/index.ts"
113
+ "@farmslot/recipe-runner",
114
+ "packages/recipe-runner/src/index.ts"
115
115
  );
116
116
  }
117
117
  async function importRecipeHarnessRuntimeCdp() {
118
118
  return importProtocolPackage(
119
- "@farmslot/recipe-harness/runtime/cdp",
120
- "packages/recipe-harness/src/runtime/cdp.ts"
119
+ "@farmslot/recipe-runner/runtime/cdp",
120
+ "packages/recipe-runner/src/runtime/cdp.ts"
121
121
  );
122
122
  }
123
123
  async function importRecipeHarnessAppLifecycle() {
124
124
  return importProtocolPackage(
125
- "@farmslot/recipe-harness/adapters/app-lifecycle",
126
- "packages/recipe-harness/src/adapters/app-lifecycle.ts"
125
+ "@farmslot/recipe-runner/adapters/app-lifecycle",
126
+ "packages/recipe-runner/src/adapters/app-lifecycle.ts"
127
127
  );
128
128
  }
129
129
  async function importRecipeHarnessRuntimeBrowserExtension() {
130
130
  return importProtocolPackage(
131
- "@farmslot/recipe-harness/runtime/browser-extension",
132
- "packages/recipe-harness/src/runtime/browser-extension.ts"
131
+ "@farmslot/recipe-runner/runtime/browser-extension",
132
+ "packages/recipe-runner/src/runtime/browser-extension.ts"
133
133
  );
134
134
  }
135
135
  async function importRecipeHarnessRuntimeReactNativeBridge() {
136
136
  return importProtocolPackage(
137
- "@farmslot/recipe-harness/runtime/react-native-bridge",
138
- "packages/recipe-harness/src/runtime/react-native-bridge.ts"
137
+ "@farmslot/recipe-runner/runtime/react-native-bridge",
138
+ "packages/recipe-runner/src/runtime/react-native-bridge.ts"
139
139
  );
140
140
  }
141
141
  async function importMetaMaskNativeUiProvider() {
@@ -144,10 +144,10 @@ async function importMetaMaskNativeUiProvider() {
144
144
  "packages/expo-recipe/src/index.ts"
145
145
  );
146
146
  }
147
- async function importRecipeHarnessCli() {
147
+ async function importRecipeRunnerCli() {
148
148
  return importProtocolPackage(
149
- "@farmslot/recipe-harness/cli",
150
- "packages/recipe-harness/src/cli/index.ts"
149
+ "@farmslot/recipe-runner/cli",
150
+ "packages/recipe-runner/src/cli/index.ts"
151
151
  );
152
152
  }
153
153
  async function importRecipeProtocol() {
@@ -185,11 +185,11 @@ export {
185
185
  importMetaMaskNativeUiProvider,
186
186
  importRecipeHarness,
187
187
  importRecipeHarnessAppLifecycle,
188
- importRecipeHarnessCli,
189
188
  importRecipeHarnessRuntimeBrowserExtension,
190
189
  importRecipeHarnessRuntimeCdp,
191
190
  importRecipeHarnessRuntimeReactNativeBridge,
192
191
  importRecipeProtocol,
192
+ importRecipeRunnerCli,
193
193
  manifestPath,
194
194
  readJson,
195
195
  recipeHarnessPath,
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import { createHash } from "node:crypto";
3
- import { loadRecipeLibraries, resolveRecipeDependencies, rootResolutionRef } from "@farmslot/recipe-harness";
3
+ import { loadRecipeLibraries, resolveRecipeDependencies, rootResolutionRef } from "@farmslot/recipe-runner";
4
4
  import { isSensitiveKey } from "./command-journal.js";
5
5
  import { resolveActionManifest } from "./manifest.js";
6
6
  import { describeManifestActions } from "./commands/manifest.js";
@@ -221,7 +221,7 @@ async function hydrateLibraryPathEnv(context) {
221
221
  if (discovered.length === 0) return;
222
222
  const entries = discovered.map((library) => `${library.name}=${library.root}`);
223
223
  if (!existing) {
224
- const { personalRecipeLibraryRoot } = await import("@farmslot/recipe-harness");
224
+ const { personalRecipeLibraryRoot } = await import("@farmslot/recipe-runner");
225
225
  const personal = personalRecipeLibraryRoot(env);
226
226
  if (isDir(personal)) entries.push(`personal=${personal}`);
227
227
  }
@@ -1,7 +1,7 @@
1
1
  import { spawn, spawnSync } from "node:child_process";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { optionalVideoTiming, readCaptureHelperTiming, writeRecordingTimeline } from "@farmslot/recipe-harness";
4
+ import { optionalVideoTiming, readCaptureHelperTiming, writeRecordingTimeline } from "@farmslot/recipe-runner";
5
5
  import { getAdapterSurface } from "./adapters/surface.js";
6
6
  import {
7
7
  captureHelperSupportsRecordSessionSnapshots,
package/dist/task-view.js CHANGED
@@ -1,4 +1,4 @@
1
- import { readOperations, processIdentity } from "@farmslot/recipe-harness/runtime/operation";
1
+ import { readOperations, processIdentity } from "@farmslot/recipe-runner/runtime/operation";
2
2
  import { spawnSync } from "node:child_process";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
@@ -13,7 +13,7 @@ bin/mm-harness
13
13
  -> @farmslot/agent-runtime checklist state
14
14
  -> @farmslot/handoff scrubbed learning capture/share
15
15
  -> @farmslot/recipe-cli recipe discovery: libraries, runnable checks, composition
16
- -> @farmslot/recipe-harness generic execution, UI transports, evidence
16
+ -> @farmslot/recipe-runner generic execution, UI transports, evidence
17
17
  -> @farmslot/protocol schemas
18
18
  -> adapters/ focused host/browser/device leaves
19
19
  -> library/ MetaMask actions and recipes
@@ -26,7 +26,7 @@ bin/mm-harness
26
26
  | `@farmslot/agent-runtime` | task-local checklist state and terminal contracts |
27
27
  | `@farmslot/handoff` | learning assembly, scrubbing, validation, approval, and publication |
28
28
  | `@farmslot/recipe-cli` | recipe discovery: library resolution, runnable checks, composition |
29
- | `@farmslot/recipe-harness` | generic execution, recovery, traces, artifacts, `ui.*` |
29
+ | `@farmslot/recipe-runner` | generic execution, recovery, traces, artifacts, `ui.*` |
30
30
  | `mm-harness` | MetaMask runtime control, diagnostics, durable domain actions |
31
31
  | skills/checklists | task workflow and proof expectations |
32
32
  | product checkout | app behavior and explicit debug hooks |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deeeed/metamask-harness",
3
- "version": "0.78.0",
3
+ "version": "0.79.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mm-harness": "bin/mm-harness"
@@ -21,13 +21,14 @@
21
21
  "check:syntax": "find . -name '*.mjs' -print0 | xargs -0 -n1 node --check"
22
22
  },
23
23
  "dependencies": {
24
+ "@farmslot/adapter-sdk": "0.1.0",
24
25
  "@farmslot/adapter-web": "0.1.0",
25
26
  "@farmslot/agent-runtime": "0.16.0",
26
- "@farmslot/expo-recipe": "0.13.1",
27
+ "@farmslot/expo-recipe": "0.14.0",
27
28
  "@farmslot/handoff": "^0.3.1",
28
29
  "@farmslot/protocol": "0.34.0",
29
- "@farmslot/recipe-cli": "0.1.2",
30
- "@farmslot/recipe-harness": "0.22.1",
30
+ "@farmslot/recipe-cli": "0.2.0",
31
+ "@farmslot/recipe-runner": "0.23.0",
31
32
  "agent-device": "0.19.3",
32
33
  "commander": "^12.0.0",
33
34
  "es-module-lexer": "2.3.1",