@deeeed/metamask-harness 0.14.5 → 0.14.7
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 +16 -1
- package/adapters/core/cleanup.sh +0 -0
- package/adapters/core/inject.sh +0 -0
- package/adapters/extension/cleanup.mjs +0 -0
- package/adapters/extension/ensure-browser.sh +0 -0
- package/adapters/extension/inject.mjs +0 -0
- package/adapters/extension/launch-browser.cjs +0 -0
- package/adapters/extension/launch.sh +0 -0
- package/adapters/extension/live.sh +0 -0
- package/adapters/extension/readiness.mjs +0 -0
- package/adapters/extension/reattach.sh +0 -0
- package/adapters/extension/refresh-build.sh +0 -0
- package/adapters/extension/seed-fixture.sh +0 -0
- package/adapters/extension/sidepanel-toggle.sh +0 -0
- package/adapters/extension/snapshot-dist.sh +0 -0
- package/adapters/extension/start-watch.sh +0 -0
- package/adapters/extension/stop-viewers.sh +0 -0
- package/adapters/extension/verify.sh +0 -0
- package/adapters/extension/wallet-fixture-state.cjs +0 -0
- package/adapters/mobile/bridge-runtime/cdp-bridge.cjs +0 -0
- package/adapters/mobile/bridge-runtime/setup-wallet.sh +0 -0
- package/adapters/mobile/cleanup.sh +0 -0
- package/adapters/mobile/inject.sh +0 -0
- package/adapters/mobile/lib/metro-listener.sh +0 -0
- package/adapters/mobile/lib/tmux-viewer.sh +0 -0
- package/adapters/mobile/open-device.sh +0 -0
- package/adapters/mobile/prewarm-bundle.sh +0 -0
- package/adapters/mobile/start-metro.sh +0 -0
- package/adapters/mobile/stop-metro.sh +0 -0
- package/adapters/mobile/verify.sh +0 -0
- package/adapters/mobile/wait-for-bridge.sh +0 -0
- package/adapters/mobile/yarn-setup.sh +0 -0
- package/adapters/shared/activate-repo-node.sh +0 -0
- package/adapters/shared/activate-repo-ruby.sh +0 -0
- package/adapters/shared/cli-ux.sh +0 -0
- package/adapters/shared/ensure-runner-deps.sh +0 -0
- package/adapters/shared/harness-path.sh +0 -0
- package/adapters/shared/hash-helpers.sh +0 -0
- package/adapters/shared/json-field.sh +0 -0
- package/adapters/shared/open-log-window.sh +0 -0
- package/adapters/shared/reap-checkout-metros.sh +0 -0
- package/adapters/shared/resolve-farmslot-ports.mjs +0 -0
- package/adapters/shared/resolve-farmslot-ports.sh +0 -0
- package/adapters/shared/resolve-slot-ports.mjs +0 -0
- package/adapters/shared/resolve-slot-ports.sh +0 -0
- package/adapters/shared/sync-wallet-fixture.sh +0 -0
- package/adapters/shared/tmux-session.sh +0 -0
- package/adapters/shared/tmux-viewer.sh +0 -0
- package/dist/adapters/mobile/surface.js +2 -1
- package/dist/cli-commands.js +1 -1
- package/dist/commands/doctor.js +47 -7
- package/dist/commands/farmslot-ready.js +25 -0
- package/dist/commands/parse-args.js +1 -0
- package/dist/mm-harness-cli.js +4 -3
- package/package.json +2 -2
- package/scripts/completions.sh +0 -0
- package/scripts/install-completions.sh +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 0.14.7 - 2026-07-10
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- `doctor --print-ready` now implies the exit-coded live probe — Farmslot `health_check` hooks need only `--print-ready`, not `--expect-live --print-ready`.
|
|
7
|
+
- Mobile `--print-ready` uses bridge `walletState` (unlocked + live bridge), not React Navigation route names; mobile `ready_indicator` is `OK`.
|
|
8
|
+
- Removed `metamask-recipe` install symlinks from adapter inject paths (no compat aliases).
|
|
9
|
+
- `doctor --print-ready` rejects `--json` (stdout is reserved for the Farmslot indicator line).
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Mobile `surface.runtimeStatus` infers Android from `ADB_SERIAL` / `ANDROID_SERIAL` when present.
|
|
13
|
+
|
|
14
|
+
## 0.14.6 - 2026-07-10
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- `mm-harness doctor --print-ready` — Farmslot `health_check` mode: prints `health.ready_indicator` on stdout (`extension`/`mobile`: `OK`; `core`: `ready`).
|
|
18
|
+
- `doctor --expect-live` — exit-coded liveness gate without indicator output (prepare recovery and other pass/fail callers).
|
|
4
19
|
|
|
5
20
|
## 0.14.5 - 2026-07-10
|
|
6
21
|
|
package/adapters/core/cleanup.sh
CHANGED
|
File without changes
|
package/adapters/core/inject.sh
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -12,7 +12,8 @@ const mobileSurface = {
|
|
|
12
12
|
},
|
|
13
13
|
async runtimeStatus(target) {
|
|
14
14
|
const watcherPort = process.env.WATCHER_PORT ? parseInt(process.env.WATCHER_PORT, 10) : void 0;
|
|
15
|
-
const
|
|
15
|
+
const platform = process.env.ADB_SERIAL || process.env.ANDROID_SERIAL ? "android" : "ios";
|
|
16
|
+
const report = await mobileRuntimeStatus(target, { watcherPort, platform });
|
|
16
17
|
const runwayProvisioned = hasRunwayProvisionBaseline(target);
|
|
17
18
|
const depsPending = runwayProvisioned && report.checks?.deps?.status !== "current";
|
|
18
19
|
return {
|
package/dist/cli-commands.js
CHANGED
|
@@ -16,7 +16,7 @@ const SPEC = {
|
|
|
16
16
|
{ name: "debug", aliases: ["devtools", "inspect"], desc: "Open DevTools UI", flags: ["--json", "--no-open"] },
|
|
17
17
|
{ name: "fixtures", desc: "Manage the canonical wallet fixture (sync/set/generate)", args: ["sync", "set", "generate"], flags: ["--fixture", "--out", "--adapter", "--target", "--device", "--json"] },
|
|
18
18
|
{ name: "actions", desc: "List runnable recipe actions", flags: ["--json"] },
|
|
19
|
-
{ name: "doctor", desc: "Check harness/orchestration health", flags: ["--json", "--target", "--adapter", "--runtime-dir", "--expect-live", "--cdp-port", "--device"] },
|
|
19
|
+
{ name: "doctor", desc: "Check harness/orchestration health", flags: ["--json", "--target", "--adapter", "--runtime-dir", "--expect-live", "--print-ready", "--cdp-port", "--device"] },
|
|
20
20
|
{ name: "run", desc: "Execute a proof recipe (path or library name, e.g. run perps.smoke)", args: ["recipe.json|name"], flags: ["--list", "--device"] },
|
|
21
21
|
{ name: "recipe-quality", desc: "Build the recipe-quality artifact from compact JSON", args: ["build"], flags: ["--input", "--output", "--json"] },
|
|
22
22
|
{ name: "interactive", aliases: ["menu"], desc: "Interactive command menu" },
|
package/dist/commands/doctor.js
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
renderMobileDeviceList,
|
|
16
16
|
renderMobileLiveBlock
|
|
17
17
|
} from "./mobile-device-view.js";
|
|
18
|
+
import { farmslotReadyIndicator } from "./farmslot-ready.js";
|
|
18
19
|
import { ADAPTER_DETECT_NEXT, EXIT, usageOut } from "./shared.js";
|
|
19
20
|
import {
|
|
20
21
|
actionManifestPathOption,
|
|
@@ -40,7 +41,8 @@ async function handleDoctor({ options }) {
|
|
|
40
41
|
applyRuntimeDirOption(options);
|
|
41
42
|
const target = targetPath(options);
|
|
42
43
|
const json = optionFlag(options, "json");
|
|
43
|
-
const
|
|
44
|
+
const printReady = optionFlag(options, "printReady");
|
|
45
|
+
const expectLive = optionFlag(options, "expectLive") || printReady;
|
|
44
46
|
const allDevices = optionFlag(options, "allDevices");
|
|
45
47
|
const platformOption = optionString(options, "platform");
|
|
46
48
|
const explicitAdapter = optionString(options, "adapter") ?? (platformOption === "ios" || platformOption === "android" ? "mobile" : platformOption);
|
|
@@ -49,6 +51,14 @@ async function handleDoctor({ options }) {
|
|
|
49
51
|
return usageOut(json, "doctor", `could not detect the MetaMask repo type for ${target}`, ADAPTER_DETECT_NEXT);
|
|
50
52
|
}
|
|
51
53
|
assertAdapter(adapter);
|
|
54
|
+
if (printReady && json) {
|
|
55
|
+
return usageOut(
|
|
56
|
+
json,
|
|
57
|
+
"doctor",
|
|
58
|
+
"--print-ready owns stdout for Farmslot health_check; drop --json (use --expect-live --json for the doctor envelope)",
|
|
59
|
+
"mm-harness doctor --print-ready --adapter <adapter> --target <path>"
|
|
60
|
+
);
|
|
61
|
+
}
|
|
52
62
|
const actionManifestPath = actionManifestPathOption(options, adapter);
|
|
53
63
|
const manifest = loadActionManifest(adapter, optionString(options, "actionManifest"));
|
|
54
64
|
const manifestValidation = await validateManifest(manifest);
|
|
@@ -80,7 +90,20 @@ async function handleDoctor({ options }) {
|
|
|
80
90
|
const liveView = deviceView ? await mobileDeviceLiveView(target, deviceView) : null;
|
|
81
91
|
const devices = liveView?.devicesWithLive ?? deviceView?.devices ?? [];
|
|
82
92
|
const additionalReachableDevices = liveView?.additionalReachableDevices ?? [];
|
|
83
|
-
if (expectLive)
|
|
93
|
+
if (expectLive) {
|
|
94
|
+
return emitExpectLive(
|
|
95
|
+
adapter,
|
|
96
|
+
target,
|
|
97
|
+
runtime,
|
|
98
|
+
result,
|
|
99
|
+
orphanMetros,
|
|
100
|
+
capture,
|
|
101
|
+
devices,
|
|
102
|
+
additionalReachableDevices,
|
|
103
|
+
json,
|
|
104
|
+
printReady
|
|
105
|
+
);
|
|
106
|
+
}
|
|
84
107
|
if (json) console.log(JSON.stringify({ ...result, runtime, orphanMetros, capture, devices, additionalReachableDevices }, null, 2));
|
|
85
108
|
else {
|
|
86
109
|
const out = (style, text) => color(style, text, { stream: process.stdout });
|
|
@@ -119,8 +142,28 @@ async function handleDoctor({ options }) {
|
|
|
119
142
|
}
|
|
120
143
|
return result.status === "pass" ? 0 : 1;
|
|
121
144
|
}
|
|
122
|
-
function
|
|
145
|
+
function emitExpectLiveVerdict(adapter, target, runtime, verdict) {
|
|
146
|
+
const out = (style, text) => color(style, text, { stream: process.stderr });
|
|
147
|
+
const detail = runtime ? `${runtime.decision}${runtime.reasonCode ? ` (${runtime.reasonCode})` : ""}` : "runtime probe unavailable";
|
|
148
|
+
console.error(`${out("err", verdict)} ${out("bold", adapter)} ${detail} ${out("dim", target)}`);
|
|
149
|
+
for (const reason of runtime?.reasons ?? []) console.error(` ${out("dim", reason)}`);
|
|
150
|
+
console.error(` Next: ${getAdapterSurface(adapter).hints.relaunch}`);
|
|
151
|
+
}
|
|
152
|
+
function emitExpectLive(adapter, target, runtime, result, orphanMetros, capture, devices, additionalReachableDevices, json, printReady) {
|
|
123
153
|
const live = runtime?.decision === "ready";
|
|
154
|
+
if (printReady) {
|
|
155
|
+
if (live) {
|
|
156
|
+
const indicator = farmslotReadyIndicator(adapter, devices);
|
|
157
|
+
if (indicator) {
|
|
158
|
+
console.log(indicator);
|
|
159
|
+
return EXIT.ok;
|
|
160
|
+
}
|
|
161
|
+
emitExpectLiveVerdict(adapter, target, runtime, "not-ready");
|
|
162
|
+
return EXIT.runtime;
|
|
163
|
+
}
|
|
164
|
+
emitExpectLiveVerdict(adapter, target, runtime, "not-live");
|
|
165
|
+
return EXIT.runtime;
|
|
166
|
+
}
|
|
124
167
|
if (json) {
|
|
125
168
|
console.log(JSON.stringify({ ...result, runtime, orphanMetros, capture, devices, additionalReachableDevices }, null, 2));
|
|
126
169
|
return live ? EXIT.ok : EXIT.runtime;
|
|
@@ -130,10 +173,7 @@ function emitExpectLive(adapter, target, runtime, result, orphanMetros, capture,
|
|
|
130
173
|
console.log(`${out("ok", "live")} ${out("bold", adapter)} runtime ready`);
|
|
131
174
|
return EXIT.ok;
|
|
132
175
|
}
|
|
133
|
-
|
|
134
|
-
console.error(`${out("err", "not-live")} ${out("bold", adapter)} ${detail} ${out("dim", target)}`);
|
|
135
|
-
for (const reason of runtime?.reasons ?? []) console.error(` ${out("dim", reason)}`);
|
|
136
|
-
console.error(` Next: ${getAdapterSurface(adapter).hints.relaunch}`);
|
|
176
|
+
emitExpectLiveVerdict(adapter, target, runtime, "not-live");
|
|
137
177
|
return EXIT.runtime;
|
|
138
178
|
}
|
|
139
179
|
function captureHelperHealth() {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function selectedDevice(devices) {
|
|
2
|
+
return devices.find((d) => d.selected) ?? devices[0];
|
|
3
|
+
}
|
|
4
|
+
function mobileWalletReady(device) {
|
|
5
|
+
if (device.liveState === "no-bridge" || device.liveState === "bridge-absent") return false;
|
|
6
|
+
return device.walletState === "unlocked";
|
|
7
|
+
}
|
|
8
|
+
function farmslotReadyIndicator(adapter, devices) {
|
|
9
|
+
switch (adapter) {
|
|
10
|
+
case "extension":
|
|
11
|
+
return "OK";
|
|
12
|
+
case "core":
|
|
13
|
+
return "ready";
|
|
14
|
+
case "mobile": {
|
|
15
|
+
const device = selectedDevice(devices);
|
|
16
|
+
if (!device) return "";
|
|
17
|
+
return mobileWalletReady(device) ? "OK" : "";
|
|
18
|
+
}
|
|
19
|
+
default:
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
farmslotReadyIndicator
|
|
25
|
+
};
|
package/dist/mm-harness-cli.js
CHANGED
|
@@ -171,19 +171,20 @@ Example:
|
|
|
171
171
|
sections so there is no hunting for files.
|
|
172
172
|
|
|
173
173
|
--fix Repair the overlay/runtime-context WITHOUT launching (no fixture reseed); --json adds fixed[]/failed[]
|
|
174
|
-
--expect-live Exit
|
|
174
|
+
--expect-live Exit-coded liveness gate only (human verdict on stderr). Use without --print-ready when callers need pass/fail without a Farmslot indicator line
|
|
175
|
+
--print-ready Farmslot health_check mode: implies --expect-live and prints health.ready_indicator on stdout (extension/mobile: OK; core: ready)
|
|
175
176
|
--cdp-port <port> Extension CDP port for the liveness probe (env: CDP_PORT / RECIPE_CDP_PORT)
|
|
176
177
|
--device <udid|serial|name> Mobile only: target this device (env: IOS_SIMULATOR / ADB_SERIAL). doctor reports the connected devices; it never gates on ambiguity.
|
|
177
178
|
--all-devices Mobile only: show every connected device instead of the slot-scoped target
|
|
178
179
|
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
179
180
|
--target <path> Checkout path (default: cwd)
|
|
180
181
|
--runtime-dir <dir> Runtime dir containing agentic-runtime.json (relative to target)
|
|
181
|
-
--json Machine-readable output
|
|
182
|
+
--json Machine-readable output (incompatible with --print-ready)
|
|
182
183
|
|
|
183
184
|
Example:
|
|
184
185
|
mm-harness doctor
|
|
185
186
|
mm-harness doctor --fix --json
|
|
186
|
-
mm-harness doctor --adapter extension --target /path/to/checkout --cdp-port 6662 --
|
|
187
|
+
mm-harness doctor --adapter extension --target /path/to/checkout --cdp-port 6662 --print-ready
|
|
187
188
|
mm-harness doctor --adapter mobile --target /path/to/checkout`
|
|
188
189
|
},
|
|
189
190
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deeeed/metamask-harness",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mm-harness": "bin/mm-harness"
|
|
@@ -70,4 +70,4 @@
|
|
|
70
70
|
"url": "https://github.com/MetaMask/experimental-metamask-harness/issues"
|
|
71
71
|
},
|
|
72
72
|
"homepage": "https://github.com/MetaMask/experimental-metamask-harness#readme"
|
|
73
|
-
}
|
|
73
|
+
}
|
package/scripts/completions.sh
CHANGED
|
File without changes
|
|
File without changes
|