@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 +8 -0
- package/adapters/shared/ensure-runner-deps.sh +2 -2
- package/adapters/shared/runner-deps-ready.mjs +1 -1
- package/adapters/terminal/lib/cdp-client.mjs +1 -1
- package/bin/mm-harness +2 -2
- package/dist/adapters/core/run.js +1 -1
- package/dist/adapters/core/surface.js +6 -4
- package/dist/adapters/extension/runtime-decision.js +1 -1
- package/dist/adapters/extension/surface.js +5 -3
- package/dist/adapters/mobile/prepare.js +1 -1
- package/dist/adapters/mobile/run.js +1 -1
- package/dist/adapters/mobile/runtime-decision.js +3 -3
- package/dist/adapters/mobile/surface.js +5 -3
- package/dist/adapters/mobile/video-recorder.js +1 -1
- package/dist/adapters/registry.js +2 -14
- package/dist/adapters/terminal/surface.js +5 -3
- package/dist/checkout-lock.js +1 -1
- package/dist/command-journal.js +1 -1
- package/dist/commands/launch/extension.js +1 -1
- package/dist/commands/prepare.js +2 -2
- package/dist/commands/shared.js +1 -1
- package/dist/discovery.js +1 -1
- package/dist/doctor.js +1 -1
- package/dist/harness.js +3 -3
- package/dist/paths.js +15 -15
- package/dist/recipe-assistance-context.js +1 -1
- package/dist/review/knowledge.js +1 -1
- package/dist/run-recording.js +1 -1
- package/dist/task-view.js +1 -1
- package/docs/CONTRIBUTING.md +2 -2
- package/package.json +5 -4
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
8
|
+
} from "@farmslot/recipe-runner/runtime/deps-readiness";
|
|
9
9
|
import {
|
|
10
10
|
analyzeBundleLog,
|
|
11
11
|
supersededErrorCapture
|
|
12
|
-
} from "@farmslot/recipe-
|
|
13
|
-
import { probeMetroPackager } from "@farmslot/recipe-
|
|
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
|
-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
package/dist/checkout-lock.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ensureRuntimeDirectory, processIdentity } from "@farmslot/recipe-
|
|
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";
|
package/dist/command-journal.js
CHANGED
|
@@ -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-
|
|
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-
|
|
9
|
+
} from "@farmslot/recipe-runner/runtime/deps-readiness";
|
|
10
10
|
import { colorHumanMessage } from "../../cli-color.js";
|
|
11
11
|
import {
|
|
12
12
|
importRecipeHarnessRuntimeCdp,
|
package/dist/commands/prepare.js
CHANGED
|
@@ -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-
|
|
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.
|
|
305
|
+
const platform = surface.id;
|
|
306
306
|
const artifactsDir = path.resolve(
|
|
307
307
|
optionString(options, "artifactsDir") ?? path.join(target, recipeRuntimeDir())
|
|
308
308
|
);
|
package/dist/commands/shared.js
CHANGED
|
@@ -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-
|
|
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-
|
|
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
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.
|
|
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.
|
|
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.
|
|
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-
|
|
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-
|
|
114
|
-
"packages/recipe-
|
|
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-
|
|
120
|
-
"packages/recipe-
|
|
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-
|
|
126
|
-
"packages/recipe-
|
|
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-
|
|
132
|
-
"packages/recipe-
|
|
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-
|
|
138
|
-
"packages/recipe-
|
|
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
|
|
147
|
+
async function importRecipeRunnerCli() {
|
|
148
148
|
return importProtocolPackage(
|
|
149
|
-
"@farmslot/recipe-
|
|
150
|
-
"packages/recipe-
|
|
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-
|
|
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";
|
package/dist/review/knowledge.js
CHANGED
|
@@ -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-
|
|
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
|
}
|
package/dist/run-recording.js
CHANGED
|
@@ -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-
|
|
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-
|
|
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";
|
package/docs/CONTRIBUTING.md
CHANGED
|
@@ -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-
|
|
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-
|
|
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.
|
|
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.
|
|
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.
|
|
30
|
-
"@farmslot/recipe-
|
|
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",
|