@deeeed/metamask-harness 0.2.0 → 0.3.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 +17 -0
- package/README.md +20 -17
- package/{orchestration → adapters}/core/cleanup.sh +2 -2
- package/{orchestration → adapters}/core/inject.sh +8 -8
- package/{orchestration → adapters}/extension/cleanup.mjs +1 -1
- package/{orchestration → adapters}/extension/console-tail.mjs +3 -0
- package/{orchestration → adapters}/extension/ensure-browser.sh +4 -4
- package/{orchestration → adapters}/extension/inject.mjs +27 -31
- package/{orchestration → adapters}/extension/launch.sh +4 -4
- package/{orchestration → adapters}/extension/live.sh +5 -5
- package/{orchestration → adapters}/extension/readiness.mjs +12 -2
- package/{orchestration → adapters}/extension/refresh-build.sh +1 -1
- package/{orchestration → adapters}/extension/seed-fixture.sh +1 -1
- package/{orchestration → adapters}/extension/start-watch.sh +7 -7
- package/{runner → adapters}/extension/verify.sh +11 -11
- package/{orchestration → adapters}/extension/wallet-fixture-state.cjs +2 -2
- package/{orchestration → adapters}/manifest.json +96 -96
- package/{library/actions → adapters}/mobile/bridge-runtime/cdp-bridge.cjs +5 -5
- package/{orchestration → adapters}/mobile/cleanup.sh +3 -3
- package/{orchestration → adapters}/mobile/inject.sh +22 -24
- package/adapters/mobile/open-device.sh +250 -0
- package/{orchestration/compat-overlays → adapters/mobile/overlay/compat}/README.md +13 -4
- package/adapters/mobile/prewarm-bundle.sh +95 -0
- package/adapters/mobile/start-metro.sh +228 -0
- package/{runner → adapters}/mobile/verify.sh +6 -6
- package/adapters/mobile/wait-for-bridge.sh +108 -0
- package/adapters/mobile/yarn-setup.sh +20 -0
- package/{orchestration/lib → adapters/shared}/cli-ux.sh +5 -9
- package/{orchestration/lib → adapters/shared}/log-tui.mjs +57 -1
- package/{orchestration/lib → adapters/shared}/open-debug.mjs +32 -10
- package/{orchestration/lib → adapters/shared}/resolve-farmslot-ports.sh +47 -0
- package/adapters/shared/sync-wallet-fixture.sh +78 -0
- package/bin/mm-harness +5 -6
- package/docs/CLI-SPEC.md +41 -2
- package/docs/architecture.md +69 -38
- package/docs/runtime-file-conventions.md +3 -3
- package/library/actions/core/perps/_controller.mjs +1 -1
- package/library/actions/extension/platform/cdp.mjs +2 -2
- package/library/actions/extension/wallet/ensure_unlocked.mjs +1 -1
- package/library/actions/mobile/platform/bridge.mjs +1 -1
- package/library/actions/mobile/wallet/ensure_unlocked.mjs +1 -1
- package/library/actions/mobile/wallet/setup.mjs +2 -2
- package/library/library.json +1 -1
- package/package.json +8 -8
- package/{orchestration → src/adapters}/extension/runtime-decision.ts +5 -5
- package/{orchestration → src/adapters}/extension/runtime.ts +1 -1
- package/src/adapters/mobile/prepare.ts +210 -0
- package/{orchestration → src/adapters}/mobile/runtime-decision.ts +11 -3
- package/{runner/src → src}/adapters.ts +3 -3
- package/{orchestration/lib/cli-color.mjs → src/cli-color.ts} +21 -13
- package/{orchestration/lib/cli-commands.mjs → src/cli-commands.ts} +52 -45
- package/{orchestration/lib/cli-version.mjs → src/cli-version.ts} +35 -17
- package/{runner/src → src}/cli.ts +25 -18
- package/src/commands/debug.ts +61 -0
- package/src/commands/fixtures.ts +196 -0
- package/{runner/src → src}/commands/launch.ts +185 -41
- package/src/commands/logs.ts +86 -0
- package/{runner/src → src}/commands/shared.ts +26 -26
- package/{runner/src → src}/harness.ts +97 -10
- package/src/index.ts +15 -0
- package/{runner/src → src}/live-adapter-contract.ts +1 -1
- package/{runner/src → src}/mm-harness-cli.ts +19 -3
- package/{runner/src → src}/paths.ts +2 -2
- package/{orchestration/lib/progress.mjs → src/progress.ts} +31 -21
- package/docs/extension-runtime-commands.md +0 -60
- package/docs/harness-cli.md +0 -43
- package/orchestration/compat-overlays/mobile/README.md +0 -13
- package/orchestration/doctor.mjs +0 -72
- package/orchestration/lib/cli-home.mjs +0 -354
- package/orchestration/lib/recipe-paths.mjs +0 -26
- package/orchestration/mobile/launch.sh +0 -137
- package/orchestration/mobile/live.sh +0 -125
- package/orchestration/porcelain/metamask-recipe +0 -99
- package/orchestration/porcelain/mm-recipe +0 -1591
- package/orchestration/porcelain/mme-recipe +0 -1181
- package/runner/src/commands/debug.ts +0 -44
- package/runner/src/commands/fixtures.ts +0 -99
- package/runner/src/commands/logs.ts +0 -60
- package/runner/src/index.ts +0 -6
- /package/{orchestration → adapters}/extension/launch-browser.cjs +0 -0
- /package/{orchestration → adapters}/extension/pin-remote-flags.cjs +0 -0
- /package/{orchestration → adapters}/extension/sidepanel-toggle.sh +0 -0
- /package/{orchestration → adapters}/extension/snapshot-dist.sh +0 -0
- /package/{library/actions → adapters}/mobile/bridge-runtime/lib/cdp-eval.cjs +0 -0
- /package/{library/actions → adapters}/mobile/bridge-runtime/lib/config.cjs +0 -0
- /package/{library/actions → adapters}/mobile/bridge-runtime/lib/issue-capture.cjs +0 -0
- /package/{library/actions → adapters}/mobile/bridge-runtime/lib/target-discovery.cjs +0 -0
- /package/{library/actions → adapters}/mobile/bridge-runtime/lib/ws-client.cjs +0 -0
- /package/{library/actions → adapters}/mobile/bridge-runtime/setup-wallet.sh +0 -0
- /package/{library/actions/mobile/app-overlay → adapters/mobile/overlay}/app/dev-tools/AgenticService/AgentStepHud.tsx.patch +0 -0
- /package/{library/actions/mobile/app-overlay → adapters/mobile/overlay}/app/dev-tools/AgenticService/AgenticService.ts.patch +0 -0
- /package/{orchestration/compat-overlays/mobile → adapters/mobile/overlay/compat}/rn81-message-event-source.patch +0 -0
- /package/{orchestration/lib → adapters/shared}/activate-repo-node.sh +0 -0
- /package/{orchestration/lib → adapters/shared}/ensure-runner-deps.sh +0 -0
- /package/{orchestration/lib → adapters/shared}/harness-path.sh +0 -0
- /package/{orchestration/lib → adapters/shared}/hash-helpers.sh +0 -0
- /package/{orchestration/lib → adapters/shared}/json-field.sh +0 -0
- /package/{orchestration/lib → adapters/shared}/path-defaults.json +0 -0
- /package/{orchestration → src/adapters}/extension/ensure-ready.ts +0 -0
- /package/{orchestration → src/adapters}/extension/extension-id.ts +0 -0
- /package/{orchestration → src/adapters}/mobile/deps-markers.ts +0 -0
- /package/{runner/src → src}/completions-cache.ts +0 -0
- /package/{runner/src → src}/doctor.ts +0 -0
- /package/{runner/src → src}/heal-bounds.ts +0 -0
- /package/{runner/src → src}/manifest.ts +0 -0
- /package/{runner/src → src}/recording-target.ts +0 -0
- /package/{runner/src → src}/run-recording.ts +0 -0
- /package/{runner/src → src}/runner.ts +0 -0
- /package/{runner/src → src}/types.ts +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# open-device — open the MetaMask Mobile dev client on a simulator or device.
|
|
3
|
+
#
|
|
4
|
+
# iOS: boots simulator if needed, writes EXDevMenuIsOnboardingFinished default,
|
|
5
|
+
# then opens via the expo-development-client deep link (disableOnboarding=1).
|
|
6
|
+
# Android: sets adb reverse for Metro port reachability, then opens via deep link.
|
|
7
|
+
# Preflight-mode guard: fast (teaching error if not installed), auto (install if missing),
|
|
8
|
+
# rebuild-native / clean (always rebuild), default (same as auto).
|
|
9
|
+
#
|
|
10
|
+
# Inputs:
|
|
11
|
+
# --platform ios|android (default ios)
|
|
12
|
+
# --target <metamask-mobile dir> (default $PWD)
|
|
13
|
+
# --simulator <udid|name|"booted"> iOS simulator (default: IOS_SIMULATOR env, else "booted")
|
|
14
|
+
# --adb-serial <serial> Android device serial (default: ADB_SERIAL env)
|
|
15
|
+
# --preflight-mode fast|auto|rebuild-native|clean (default: fast; env MOBILE_PREFLIGHT_MODE)
|
|
16
|
+
# Outputs:
|
|
17
|
+
# Progress on stderr; exit 0 pass; 1 open failed; 2 bad args.
|
|
18
|
+
#
|
|
19
|
+
# Single device op: open the dev client. Does not start Metro or install node_modules.
|
|
20
|
+
set -uo pipefail
|
|
21
|
+
|
|
22
|
+
PLATFORM="ios"
|
|
23
|
+
TARGET="$PWD"
|
|
24
|
+
SIMULATOR="${IOS_SIMULATOR:-${SIM_UDID:-booted}}"
|
|
25
|
+
ADB_SERIAL_ARG="${ADB_SERIAL:-${ANDROID_SERIAL:-}}"
|
|
26
|
+
PREFLIGHT_MODE="${MOBILE_PREFLIGHT_MODE:-fast}"
|
|
27
|
+
PORT="${WATCHER_PORT:-${METRO_PORT:-8081}}"
|
|
28
|
+
|
|
29
|
+
while [ "$#" -gt 0 ]; do
|
|
30
|
+
case "$1" in
|
|
31
|
+
--platform) PLATFORM="$2"; shift 2 ;;
|
|
32
|
+
--target) TARGET="$2"; shift 2 ;;
|
|
33
|
+
--simulator) SIMULATOR="$2"; shift 2 ;;
|
|
34
|
+
--adb-serial) ADB_SERIAL_ARG="$2"; shift 2 ;;
|
|
35
|
+
--preflight-mode) PREFLIGHT_MODE="$2"; shift 2 ;;
|
|
36
|
+
--port) PORT="$2"; shift 2 ;;
|
|
37
|
+
-h|--help)
|
|
38
|
+
printf 'Usage: open-device.sh [--platform ios|android] [--target <dir>]\n'
|
|
39
|
+
printf ' [--simulator <udid|name|booted>] [--adb-serial <serial>]\n'
|
|
40
|
+
printf ' [--preflight-mode fast|auto|rebuild-native|clean] [--port <n>]\n'
|
|
41
|
+
exit 0
|
|
42
|
+
;;
|
|
43
|
+
*) printf 'open-device: unknown arg: %s\n' "$1" >&2; exit 2 ;;
|
|
44
|
+
esac
|
|
45
|
+
done
|
|
46
|
+
|
|
47
|
+
case "$PLATFORM" in
|
|
48
|
+
ios|android) ;;
|
|
49
|
+
*) printf 'open-device: --platform must be ios or android (got: %s)\n' "$PLATFORM" >&2; exit 2 ;;
|
|
50
|
+
esac
|
|
51
|
+
|
|
52
|
+
TARGET="$(cd "$TARGET" && pwd)"
|
|
53
|
+
|
|
54
|
+
# --- iOS helpers --------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
ios_app_installed() {
|
|
57
|
+
local sim_target="$1" bundle_id="$2"
|
|
58
|
+
xcrun simctl get_app_container "$sim_target" "$bundle_id" app >/dev/null 2>&1
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
run_ios_native_build() {
|
|
62
|
+
local sim_target="$1" reason="$2"
|
|
63
|
+
printf '%s; installing with yarn start:ios (WATCHER_PORT=%s)\n' "$reason" "$PORT" >&2
|
|
64
|
+
(cd "$TARGET" && WATCHER_PORT="$PORT" METRO_PORT="$PORT" IOS_SIMULATOR="$sim_target" EXPO_NO_TYPESCRIPT_SETUP=1 yarn start:ios 2>&1)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
ensure_ios_app_for_mode() {
|
|
68
|
+
local sim_target="$1" bundle_id="$2" mode="$3"
|
|
69
|
+
case "$mode" in
|
|
70
|
+
fast)
|
|
71
|
+
if ios_app_installed "$sim_target" "$bundle_id"; then return 0; fi
|
|
72
|
+
printf >&2 'open-device: fast mode requires an installed iOS dev client (%s) on %s.\n' \
|
|
73
|
+
"$bundle_id" "$sim_target"
|
|
74
|
+
printf >&2 'Fast mode only prewarms the bundle and opens the existing client.\n'
|
|
75
|
+
printf >&2 'Next: use --preflight-mode auto to install if missing.\n'
|
|
76
|
+
return 1
|
|
77
|
+
;;
|
|
78
|
+
auto|default)
|
|
79
|
+
if ios_app_installed "$sim_target" "$bundle_id"; then return 0; fi
|
|
80
|
+
run_ios_native_build "$sim_target" "iOS dev client ${bundle_id} not installed on ${sim_target}"
|
|
81
|
+
;;
|
|
82
|
+
rebuild-native|clean)
|
|
83
|
+
run_ios_native_build "$sim_target" "Rebuilding iOS dev client ${bundle_id} (--preflight-mode ${mode})"
|
|
84
|
+
;;
|
|
85
|
+
*)
|
|
86
|
+
printf 'open-device: unknown --preflight-mode: %s\n' "$mode" >&2; return 2 ;;
|
|
87
|
+
esac
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
sim_udid_for_target() {
|
|
91
|
+
local target="$1"
|
|
92
|
+
# Already a UDID
|
|
93
|
+
if printf '%s' "$target" | grep -Eq '^[0-9A-Fa-f-]{36}$'; then
|
|
94
|
+
printf '%s\n' "$target"; return 0
|
|
95
|
+
fi
|
|
96
|
+
xcrun simctl list devices available 2>/dev/null \
|
|
97
|
+
| sed -n "s/.*${target} (\([0-9A-Fa-f-]*\)) (.*/\1/p" | head -1
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
boot_simulator_if_needed() {
|
|
101
|
+
local target="$1" state=""
|
|
102
|
+
[ "$target" != "booted" ] || return 0
|
|
103
|
+
local line=""
|
|
104
|
+
line="$(xcrun simctl list devices available 2>/dev/null | grep -F "${target} (" | head -1 || true)"
|
|
105
|
+
case "$line" in *"(Booted)"*) state="Booted" ;; *"(Shutdown)"*) state="Shutdown" ;; esac
|
|
106
|
+
[ "$state" = "Booted" ] && return 0
|
|
107
|
+
printf 'Booting iOS simulator %s%s\n' "$target" "${state:+ ($state)}" >&2
|
|
108
|
+
xcrun simctl boot "$target" 2>/dev/null || true
|
|
109
|
+
xcrun simctl bootstatus "$target" -b >/dev/null
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
show_simulator() {
|
|
113
|
+
local target="$1" udid=""
|
|
114
|
+
if [ "$target" = "booted" ]; then
|
|
115
|
+
printf 'Opening Simulator UI\n' >&2
|
|
116
|
+
open -a Simulator >/dev/null 2>&1 || true
|
|
117
|
+
else
|
|
118
|
+
udid="$(sim_udid_for_target "$target")"
|
|
119
|
+
if [ -n "$udid" ]; then
|
|
120
|
+
open -a Simulator --args -CurrentDeviceUDID "$udid" >/dev/null 2>&1 || true
|
|
121
|
+
else
|
|
122
|
+
open -a Simulator >/dev/null 2>&1 || true
|
|
123
|
+
fi
|
|
124
|
+
fi
|
|
125
|
+
osascript -e 'tell application "Simulator" to activate' >/dev/null 2>&1 || true
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# --- Android helpers ----------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
android_app_installed() {
|
|
131
|
+
local pkg="$1"
|
|
132
|
+
shift
|
|
133
|
+
adb "$@" shell pm list packages 2>/dev/null | grep -q "package:${pkg}"
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
run_android_native_build() {
|
|
137
|
+
local reason="$1"
|
|
138
|
+
printf '%s; installing with yarn start:android (WATCHER_PORT=%s)\n' "$reason" "$PORT" >&2
|
|
139
|
+
(cd "$TARGET" && WATCHER_PORT="$PORT" yarn start:android 2>&1)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
ensure_android_app_for_mode() {
|
|
143
|
+
local pkg="$1" mode="$2"
|
|
144
|
+
shift 2
|
|
145
|
+
case "$mode" in
|
|
146
|
+
fast)
|
|
147
|
+
if android_app_installed "$pkg" "$@"; then return 0; fi
|
|
148
|
+
printf >&2 'open-device: fast mode requires an installed Android dev client (%s).\n' "$pkg"
|
|
149
|
+
printf >&2 'Next: use --preflight-mode auto to install if missing.\n'
|
|
150
|
+
return 1
|
|
151
|
+
;;
|
|
152
|
+
auto|default)
|
|
153
|
+
if android_app_installed "$pkg" "$@"; then return 0; fi
|
|
154
|
+
run_android_native_build "Android dev client ${pkg} not installed"
|
|
155
|
+
;;
|
|
156
|
+
rebuild-native|clean)
|
|
157
|
+
run_android_native_build "Rebuilding Android dev client ${pkg} (--preflight-mode ${mode})"
|
|
158
|
+
;;
|
|
159
|
+
*)
|
|
160
|
+
printf 'open-device: unknown --preflight-mode: %s\n' "$mode" >&2; return 2 ;;
|
|
161
|
+
esac
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# URL-encode using python3 (same as baseline).
|
|
165
|
+
urlencode() {
|
|
166
|
+
python3 - "$1" <<'PY'
|
|
167
|
+
import sys, urllib.parse
|
|
168
|
+
print(urllib.parse.quote(sys.argv[1], safe=''))
|
|
169
|
+
PY
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
# --- dispatch -----------------------------------------------------------------
|
|
173
|
+
|
|
174
|
+
BUNDLE_IDS=("${IOS_BUNDLE_ID:-io.metamask.MetaMask}" "io.metamask" "io.metamask.flask" "io.metamask.qa")
|
|
175
|
+
ANDROID_PKGS=("${ANDROID_PACKAGE_ID:-io.metamask}" "io.metamask.flask" "io.metamask.qa")
|
|
176
|
+
|
|
177
|
+
if [ "$PLATFORM" = "ios" ]; then
|
|
178
|
+
SIM_TARGET="$SIMULATOR"
|
|
179
|
+
|
|
180
|
+
boot_simulator_if_needed "$SIM_TARGET"
|
|
181
|
+
show_simulator "$SIM_TARGET"
|
|
182
|
+
|
|
183
|
+
LAUNCHED=false
|
|
184
|
+
for BUNDLE_ID in "${BUNDLE_IDS[@]}"; do
|
|
185
|
+
ensure_ios_app_for_mode "$SIM_TARGET" "$BUNDLE_ID" "$PREFLIGHT_MODE" || continue
|
|
186
|
+
|
|
187
|
+
# Dismiss Expo dev-menu onboarding for clean headless runs.
|
|
188
|
+
xcrun simctl spawn "$SIM_TARGET" defaults write "$BUNDLE_ID" \
|
|
189
|
+
EXDevMenuIsOnboardingFinished -bool YES 2>/dev/null || true
|
|
190
|
+
|
|
191
|
+
# Open via expo-development-client deep link so the app connects to our Metro.
|
|
192
|
+
ENCODED_URL="$(urlencode "http://localhost:${PORT}?disableOnboarding=1" 2>/dev/null \
|
|
193
|
+
|| printf 'http%%3A%%2F%%2Flocalhost%%3A%s%%3FdisableOnboarding%%3D1' "$PORT")"
|
|
194
|
+
DEEP_LINK="expo-metamask://expo-development-client/?url=${ENCODED_URL}"
|
|
195
|
+
|
|
196
|
+
printf 'Launching iOS dev client %s on %s\n' "$BUNDLE_ID" "$SIM_TARGET" >&2
|
|
197
|
+
if xcrun simctl openurl "$SIM_TARGET" "$DEEP_LINK" 2>/dev/null; then
|
|
198
|
+
LAUNCHED=true
|
|
199
|
+
printf 'open-device: iOS dev client opened (%s on %s)\n' "$BUNDLE_ID" "$SIM_TARGET" >&2
|
|
200
|
+
break
|
|
201
|
+
fi
|
|
202
|
+
# Fallback: plain launch (older Expo / non-development-client build).
|
|
203
|
+
if xcrun simctl launch "$SIM_TARGET" "$BUNDLE_ID" 2>/dev/null; then
|
|
204
|
+
LAUNCHED=true
|
|
205
|
+
printf 'open-device: iOS dev client launched (fallback) (%s on %s)\n' "$BUNDLE_ID" "$SIM_TARGET" >&2
|
|
206
|
+
break
|
|
207
|
+
fi
|
|
208
|
+
done
|
|
209
|
+
|
|
210
|
+
if [ "$LAUNCHED" = false ]; then
|
|
211
|
+
printf 'open-device: no MetaMask bundle found on simulator %s\n' "$SIM_TARGET" >&2
|
|
212
|
+
printf ' tried: %s\n' "${BUNDLE_IDS[*]}" >&2
|
|
213
|
+
exit 1
|
|
214
|
+
fi
|
|
215
|
+
|
|
216
|
+
else
|
|
217
|
+
ADB_ARGS=()
|
|
218
|
+
[ -n "$ADB_SERIAL_ARG" ] && ADB_ARGS+=("-s" "$ADB_SERIAL_ARG")
|
|
219
|
+
|
|
220
|
+
# Reverse-tunnel Metro port so the device can reach localhost:PORT.
|
|
221
|
+
adb "${ADB_ARGS[@]}" reverse "tcp:${PORT}" "tcp:${PORT}" >/dev/null 2>&1 || \
|
|
222
|
+
printf 'open-device: adb reverse failed (non-fatal — device may already be reachable)\n' >&2
|
|
223
|
+
|
|
224
|
+
LAUNCHED=false
|
|
225
|
+
for PKG in "${ANDROID_PKGS[@]}"; do
|
|
226
|
+
ensure_android_app_for_mode "$PKG" "$PREFLIGHT_MODE" "${ADB_ARGS[@]}" || continue
|
|
227
|
+
|
|
228
|
+
ENCODED_URL="$(urlencode "http://localhost:${PORT}?disableOnboarding=1" 2>/dev/null \
|
|
229
|
+
|| printf 'http%%3A%%2F%%2Flocalhost%%3A%s%%3FdisableOnboarding%%3D1' "$PORT")"
|
|
230
|
+
DEEP_LINK="expo-metamask://expo-development-client/?url=${ENCODED_URL}"
|
|
231
|
+
|
|
232
|
+
printf 'Launching Android dev client %s\n' "$PKG" >&2
|
|
233
|
+
if adb "${ADB_ARGS[@]}" shell am start \
|
|
234
|
+
-a android.intent.action.VIEW \
|
|
235
|
+
-d "$DEEP_LINK" >/dev/null 2>&1; then
|
|
236
|
+
LAUNCHED=true
|
|
237
|
+
printf 'open-device: Android dev client opened (%s)\n' "$PKG" >&2
|
|
238
|
+
break
|
|
239
|
+
fi
|
|
240
|
+
done
|
|
241
|
+
|
|
242
|
+
if [ "$LAUNCHED" = false ]; then
|
|
243
|
+
printf 'open-device: no MetaMask package found on Android device %s\n' \
|
|
244
|
+
"${ADB_SERIAL_ARG:-<default>}" >&2
|
|
245
|
+
printf ' tried: %s\n' "${ANDROID_PKGS[*]}" >&2
|
|
246
|
+
exit 1
|
|
247
|
+
fi
|
|
248
|
+
fi
|
|
249
|
+
|
|
250
|
+
printf ' Next: mm-harness logs # tail Metro\n' >&2
|
|
@@ -7,13 +7,22 @@ up empty here by design: the feature's purpose is non-current checkouts.
|
|
|
7
7
|
|
|
8
8
|
- Purpose: make historical product checkouts bootable/bridgeable under the
|
|
9
9
|
current local toolchain so Recipe v1 evals can replay against them.
|
|
10
|
-
- When it applies: mobile checkouts predating React Native 0.81 polyfill
|
|
11
|
-
fixes (see mobile/README.md for the per-patch details).
|
|
10
|
+
- When it applies: mobile checkouts predating React Native 0.81 polyfill fixes.
|
|
12
11
|
- How it is applied: MANUALLY (no automatic apply logic in this repo).
|
|
13
12
|
The operator or the `/recipe-harness` skill applies the patch reversibly
|
|
14
13
|
before a historical rebuild (`git apply <patch>` in the product checkout,
|
|
15
14
|
`git apply -R` to remove) and records the overlay path in validation
|
|
16
|
-
evidence. `
|
|
15
|
+
evidence. `adapters/mobile/inject.sh` does NOT apply these.
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
Kept in the external runner repository, not Farmslot root scripts, so a
|
|
18
|
+
`/recipe-harness` skill can apply the same reversible overlay before a
|
|
19
|
+
historical rebuild and record the overlay path in validation evidence.
|
|
20
|
+
|
|
21
|
+
Listed in adapters/manifest.json (kind: compat-overlay) so the doctor
|
|
19
22
|
verifies the surface and this directory is never flagged as unused again.
|
|
23
|
+
|
|
24
|
+
## Patches
|
|
25
|
+
|
|
26
|
+
- `rn81-message-event-source.patch`: adds a read-only `MessageEvent.prototype.source`
|
|
27
|
+
getter for React Native 0.81 historical checkouts whose bundled polyfill omits
|
|
28
|
+
it while CDP websocket clients expect browser-compatible `MessageEvent` shape.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# prewarm-bundle — curl the Metro bundle URL before the dev client opens.
|
|
3
|
+
#
|
|
4
|
+
# Triggers Metro to compile and cache the bundle so the app connects instantly.
|
|
5
|
+
# Streams progress from the Metro log every 30s until the bundle curl finishes
|
|
6
|
+
# or MOBILE_BUNDLE_PREWARM_TIMEOUT seconds elapse.
|
|
7
|
+
# Set MOBILE_BUNDLE_PREWARM=0 to skip.
|
|
8
|
+
#
|
|
9
|
+
# Inputs:
|
|
10
|
+
# --platform ios|android (default ios)
|
|
11
|
+
# --target <metamask-mobile dir> (default $PWD)
|
|
12
|
+
# --port <number> (default WATCHER_PORT env, else METRO_PORT, else 8081)
|
|
13
|
+
# Outputs:
|
|
14
|
+
# Progress on stderr; exit 0 bundle ready; 1 timeout or curl error; 2 bad args.
|
|
15
|
+
#
|
|
16
|
+
# Single device op: prewarm the bundle. Does not start Metro or open the dev client.
|
|
17
|
+
set -uo pipefail
|
|
18
|
+
|
|
19
|
+
PLATFORM="ios"
|
|
20
|
+
TARGET="$PWD"
|
|
21
|
+
PORT="${WATCHER_PORT:-${METRO_PORT:-8081}}"
|
|
22
|
+
|
|
23
|
+
while [ "$#" -gt 0 ]; do
|
|
24
|
+
case "$1" in
|
|
25
|
+
--platform) PLATFORM="$2"; shift 2 ;;
|
|
26
|
+
--target) TARGET="$2"; shift 2 ;;
|
|
27
|
+
--port) PORT="$2"; shift 2 ;;
|
|
28
|
+
-h|--help)
|
|
29
|
+
printf 'Usage: prewarm-bundle.sh [--platform ios|android] [--target <dir>] [--port <n>]\n'
|
|
30
|
+
exit 0
|
|
31
|
+
;;
|
|
32
|
+
*) printf 'prewarm-bundle: unknown arg: %s\n' "$1" >&2; exit 2 ;;
|
|
33
|
+
esac
|
|
34
|
+
done
|
|
35
|
+
|
|
36
|
+
case "$PLATFORM" in
|
|
37
|
+
ios|android) ;;
|
|
38
|
+
*) printf 'prewarm-bundle: --platform must be ios or android (got: %s)\n' "$PLATFORM" >&2; exit 2 ;;
|
|
39
|
+
esac
|
|
40
|
+
|
|
41
|
+
TARGET="$(cd "$TARGET" && pwd)"
|
|
42
|
+
LOG_DIR="$TARGET/temp/recipe/runtime"
|
|
43
|
+
mkdir -p "$LOG_DIR"
|
|
44
|
+
METRO_LOG="$LOG_DIR/metro.log"
|
|
45
|
+
|
|
46
|
+
if [ "${MOBILE_BUNDLE_PREWARM:-1}" = "0" ]; then
|
|
47
|
+
printf 'Skipping %s bundle prewarm (MOBILE_BUNDLE_PREWARM=0)\n' "$PLATFORM" >&2
|
|
48
|
+
exit 0
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
TIMEOUT="${MOBILE_BUNDLE_PREWARM_TIMEOUT:-900}"
|
|
52
|
+
|
|
53
|
+
BUNDLE_URL="http://localhost:${PORT}/index.bundle?platform=${PLATFORM}&dev=true&hot=false&lazy=true&transform.engine=hermes&transform.bytecode=1&transform.routerRoot=app&unstable_transformProfile=hermes-stable"
|
|
54
|
+
|
|
55
|
+
printf 'Prewarming %s bundle before launching dev client (set MOBILE_BUNDLE_PREWARM=0 to skip)\n' "$PLATFORM" >&2
|
|
56
|
+
printf ' url: %s\n' "$BUNDLE_URL" >&2
|
|
57
|
+
|
|
58
|
+
curl -sfL --connect-timeout 5 --max-time "$TIMEOUT" -o /dev/null "$BUNDLE_URL" &
|
|
59
|
+
BUNDLE_PID=$!
|
|
60
|
+
|
|
61
|
+
ELAPSED=0
|
|
62
|
+
LAST_PROGRESS=""
|
|
63
|
+
while kill -0 "$BUNDLE_PID" 2>/dev/null; do
|
|
64
|
+
PROGRESS=""
|
|
65
|
+
if [ -f "$METRO_LOG" ]; then
|
|
66
|
+
PROGRESS="$(grep -E '^[[:space:]]*(iOS|Android).*index\.(js|tsx?).*%|Bundl(ed|ing)|Finished' "$METRO_LOG" 2>/dev/null | tail -1 | tr -d '\r' || true)"
|
|
67
|
+
fi
|
|
68
|
+
if [ -n "$PROGRESS" ] && [ "$PROGRESS" != "$LAST_PROGRESS" ]; then
|
|
69
|
+
printf 'Bundle progress: %s\n' "$PROGRESS" >&2
|
|
70
|
+
LAST_PROGRESS="$PROGRESS"
|
|
71
|
+
elif [ $((ELAPSED % 30)) -eq 0 ] && [ "$ELAPSED" -gt 0 ]; then
|
|
72
|
+
printf 'Waiting for %s bundle (%ss/%ss)%s\n' "$PLATFORM" "$ELAPSED" "$TIMEOUT" \
|
|
73
|
+
"${LAST_PROGRESS:+ — $LAST_PROGRESS}" >&2
|
|
74
|
+
fi
|
|
75
|
+
if [ "$ELAPSED" -ge "$TIMEOUT" ]; then
|
|
76
|
+
kill "$BUNDLE_PID" 2>/dev/null || true
|
|
77
|
+
wait "$BUNDLE_PID" 2>/dev/null || true
|
|
78
|
+
printf 'prewarm-bundle: %s bundle did not become ready before timeout (%ss)\n' "$PLATFORM" "$TIMEOUT" >&2
|
|
79
|
+
[ -f "$METRO_LOG" ] && tail -80 "$METRO_LOG" >&2 || true
|
|
80
|
+
printf ' Next: check %s for errors or reduce MOBILE_BUNDLE_PREWARM_TIMEOUT\n' "$METRO_LOG" >&2
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
sleep 3
|
|
84
|
+
ELAPSED=$((ELAPSED + 3))
|
|
85
|
+
done
|
|
86
|
+
|
|
87
|
+
if wait "$BUNDLE_PID"; then
|
|
88
|
+
printf '%s bundle ready\n' "$PLATFORM" >&2
|
|
89
|
+
exit 0
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
printf 'prewarm-bundle: %s bundle curl failed\n' "$PLATFORM" >&2
|
|
93
|
+
[ -f "$METRO_LOG" ] && tail -80 "$METRO_LOG" >&2 || true
|
|
94
|
+
printf ' Next: check %s for Metro errors\n' "$METRO_LOG" >&2
|
|
95
|
+
exit 1
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# start-metro — ensure the Metro bundler is running for this MetaMask Mobile checkout.
|
|
3
|
+
#
|
|
4
|
+
# Checks if Metro is already running and owned by this checkout with required env vars.
|
|
5
|
+
# Clears stale or foreign listeners before starting. Uses yarn expo start --port (not
|
|
6
|
+
# yarn start), sources .js.env/.env/.env.local, sets EXPO_NO_TYPESCRIPT_SETUP=1, and
|
|
7
|
+
# caps METRO_MAX_WORKERS to 6 (or the physical CPU count).
|
|
8
|
+
#
|
|
9
|
+
# Inputs:
|
|
10
|
+
# --target <metamask-mobile dir> (default $PWD)
|
|
11
|
+
# --port <number> (default: WATCHER_PORT env, else METRO_PORT, else 8081)
|
|
12
|
+
# --clear reset Metro bundler cache before starting
|
|
13
|
+
# Outputs:
|
|
14
|
+
# Progress on stderr; exit 0 Metro ready; 1 failed to start; 2 bad args.
|
|
15
|
+
#
|
|
16
|
+
# Single device op: ensure Metro is running. Does not open the dev client or install deps.
|
|
17
|
+
set -uo pipefail
|
|
18
|
+
|
|
19
|
+
TARGET="$PWD"
|
|
20
|
+
PORT="${WATCHER_PORT:-${METRO_PORT:-8081}}"
|
|
21
|
+
CLEAR=false
|
|
22
|
+
|
|
23
|
+
while [ "$#" -gt 0 ]; do
|
|
24
|
+
case "$1" in
|
|
25
|
+
--target) TARGET="$2"; shift 2 ;;
|
|
26
|
+
--port) PORT="$2"; shift 2 ;;
|
|
27
|
+
--clear) CLEAR=true; shift ;;
|
|
28
|
+
-h|--help)
|
|
29
|
+
printf 'Usage: start-metro.sh [--target <dir>] [--port <port>] [--clear]\n'
|
|
30
|
+
printf ' --target MetaMask Mobile checkout directory\n'
|
|
31
|
+
printf ' --port Metro port (default: WATCHER_PORT env or 8081)\n'
|
|
32
|
+
printf ' --clear restart with cleared cache\n'
|
|
33
|
+
exit 0
|
|
34
|
+
;;
|
|
35
|
+
*) printf 'start-metro: unknown arg: %s\n' "$1" >&2; exit 2 ;;
|
|
36
|
+
esac
|
|
37
|
+
done
|
|
38
|
+
|
|
39
|
+
TARGET="$(cd "$TARGET" && pwd)"
|
|
40
|
+
LOG_DIR="$TARGET/temp/recipe/runtime"
|
|
41
|
+
mkdir -p "$LOG_DIR"
|
|
42
|
+
LOG_FILE="$LOG_DIR/metro.log"
|
|
43
|
+
PID_FILE="$LOG_DIR/metro.pid"
|
|
44
|
+
|
|
45
|
+
# --- helpers ------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
metro_ready() {
|
|
48
|
+
curl -sf --max-time 2 "http://localhost:${PORT}/status" 2>/dev/null | grep -q 'packager-status:running'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
metro_listener_pids() {
|
|
52
|
+
lsof -nP -iTCP:"${PORT}" -sTCP:LISTEN -t 2>/dev/null | tr '\n' ' ' || true
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
metro_listener_valid() {
|
|
56
|
+
local pids pid command rv
|
|
57
|
+
pids="$(metro_listener_pids)"
|
|
58
|
+
[ -n "$(printf '%s' "$pids" | tr -d ' ')" ] || return 1
|
|
59
|
+
rv=0
|
|
60
|
+
for pid in $pids; do
|
|
61
|
+
command="$(ps eww -p "$pid" -o command= 2>/dev/null || true)"
|
|
62
|
+
case "$command" in
|
|
63
|
+
*"$TARGET"*) ;;
|
|
64
|
+
*)
|
|
65
|
+
printf 'Metro on port %s not owned by this checkout (pid %s); restarting\n' "$PORT" "$pid" >&2
|
|
66
|
+
rv=1; break
|
|
67
|
+
;;
|
|
68
|
+
esac
|
|
69
|
+
for required_var in ${MOBILE_METRO_REQUIRED_ENV:-MM_INFURA_PROJECT_ID}; do
|
|
70
|
+
if ! printf '%s\n' "$command" | grep -Eq "(^|[[:space:]])${required_var}="; then
|
|
71
|
+
printf 'Metro on port %s missing required env %s (pid %s); restarting\n' "$PORT" "$required_var" "$pid" >&2
|
|
72
|
+
rv=1; break 2
|
|
73
|
+
fi
|
|
74
|
+
done
|
|
75
|
+
done
|
|
76
|
+
return "$rv"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
stop_metro_listener() {
|
|
80
|
+
local pids i
|
|
81
|
+
pids="$(metro_listener_pids)"
|
|
82
|
+
[ -n "$(printf '%s' "$pids" | tr -d ' ')" ] || return 0
|
|
83
|
+
printf 'Stopping Metro listener on port %s: %s\n' "$PORT" "$pids" >&2
|
|
84
|
+
# shellcheck disable=SC2086
|
|
85
|
+
kill $pids 2>/dev/null || true
|
|
86
|
+
for i in $(seq 1 20); do
|
|
87
|
+
pids="$(metro_listener_pids)"
|
|
88
|
+
[ -z "$(printf '%s' "$pids" | tr -d ' ')" ] && return 0
|
|
89
|
+
sleep 0.25
|
|
90
|
+
done
|
|
91
|
+
printf 'Metro listener still held; force-killing: %s\n' "$pids" >&2
|
|
92
|
+
# shellcheck disable=SC2086
|
|
93
|
+
kill -KILL $pids 2>/dev/null || true
|
|
94
|
+
for i in $(seq 1 20); do
|
|
95
|
+
pids="$(metro_listener_pids)"
|
|
96
|
+
[ -z "$(printf '%s' "$pids" | tr -d ' ')" ] && return 0
|
|
97
|
+
sleep 0.25
|
|
98
|
+
done
|
|
99
|
+
printf 'start-metro: port %s still occupied after force-kill: %s\n' "$PORT" "$pids" >&2
|
|
100
|
+
return 1
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
default_metro_workers() {
|
|
104
|
+
local cores=""
|
|
105
|
+
if command -v sysctl >/dev/null 2>&1; then
|
|
106
|
+
cores="$(sysctl -n hw.perflevel0.physicalcpu 2>/dev/null || sysctl -n hw.physicalcpu 2>/dev/null || true)"
|
|
107
|
+
fi
|
|
108
|
+
if printf '%s' "${cores:-}" | grep -Eq '^[0-9]+$' && [ "${cores:-0}" -gt 0 ]; then
|
|
109
|
+
[ "${cores:-4}" -gt 6 ] && cores=6
|
|
110
|
+
printf '%s\n' "$cores"
|
|
111
|
+
else
|
|
112
|
+
printf '4\n'
|
|
113
|
+
fi
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
start_viewer_window() {
|
|
117
|
+
local metro_log="$1"
|
|
118
|
+
command -v tmux >/dev/null 2>&1 || return 0
|
|
119
|
+
local window="metro-${PORT}"
|
|
120
|
+
local metro_tmux="$LOG_DIR/metro.tmux"
|
|
121
|
+
local session=""
|
|
122
|
+
if [ -n "${slot:-}" ] && tmux has-session -t "=mm-${slot}" 2>/dev/null; then
|
|
123
|
+
session="mm-${slot}"
|
|
124
|
+
fi
|
|
125
|
+
if [ -z "$session" ]; then
|
|
126
|
+
session="$(tmux display-message -p '#S' 2>/dev/null || true)"
|
|
127
|
+
fi
|
|
128
|
+
[ -n "$session" ] || return 0
|
|
129
|
+
tmux kill-window -t "${session}:${window}" >/dev/null 2>&1 || true
|
|
130
|
+
tmux new-window -d -t "$session" -n "$window" "exec tail -n +1 -F $(printf '%q' "$metro_log")"
|
|
131
|
+
printf '%s:%s\n' "$session" "$window" > "$metro_tmux"
|
|
132
|
+
printf 'Metro log viewer → tmux %s:%s\n' "$session" "$window" >&2
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# --- main ---------------------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
# Decide whether to (re)start or skip.
|
|
138
|
+
if metro_ready; then
|
|
139
|
+
if [ "$CLEAR" = true ]; then
|
|
140
|
+
printf 'Restarting Metro on port %s with cleared cache\n' "$PORT" >&2
|
|
141
|
+
stop_metro_listener || exit 1
|
|
142
|
+
rm -f "$PID_FILE"
|
|
143
|
+
elif metro_listener_valid; then
|
|
144
|
+
printf 'Metro already running and valid on port %s\n' "$PORT" >&2
|
|
145
|
+
exit 0
|
|
146
|
+
else
|
|
147
|
+
stop_metro_listener || exit 1
|
|
148
|
+
rm -f "$PID_FILE"
|
|
149
|
+
fi
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
stop_metro_listener || exit 1
|
|
153
|
+
|
|
154
|
+
METRO_WORKERS="${METRO_MAX_WORKERS:-$(default_metro_workers)}"
|
|
155
|
+
CLEAR_SUFFIX=""
|
|
156
|
+
[ "$CLEAR" = true ] && CLEAR_SUFFIX=" --clear"
|
|
157
|
+
|
|
158
|
+
printf 'Starting Metro on port %s (workers=%s%s)\n' \
|
|
159
|
+
"$PORT" "$METRO_WORKERS" "${CLEAR:+, clear}" >&2
|
|
160
|
+
printf '(Full log: %s — recipe logs | recipe logs --full)\n' "$LOG_FILE" >&2
|
|
161
|
+
|
|
162
|
+
# Metro runs detached, writing to the log. The tmux window is a read-only tail.
|
|
163
|
+
(
|
|
164
|
+
cd "$TARGET"
|
|
165
|
+
: > "$LOG_FILE"
|
|
166
|
+
# Source product env files (provides MM_INFURA_PROJECT_ID and friends).
|
|
167
|
+
set -a
|
|
168
|
+
# shellcheck disable=SC1091
|
|
169
|
+
[ ! -f .js.env ] || . ./.js.env
|
|
170
|
+
# shellcheck disable=SC1091
|
|
171
|
+
[ ! -f .env ] || . ./.env
|
|
172
|
+
# shellcheck disable=SC1091
|
|
173
|
+
[ ! -f .env.local ] || . ./.env.local
|
|
174
|
+
set +a
|
|
175
|
+
export EXPO_NO_TYPESCRIPT_SETUP=1
|
|
176
|
+
export WATCHER_PORT="${PORT}" METRO_PORT="${PORT}"
|
|
177
|
+
export METRO_MAX_WORKERS="${METRO_WORKERS}"
|
|
178
|
+
# shellcheck disable=SC2094
|
|
179
|
+
bash -c "exec yarn expo start --port ${PORT}${CLEAR_SUFFIX}" \
|
|
180
|
+
</dev/null >> "$LOG_FILE" 2>&1 &
|
|
181
|
+
echo "$!" > "$PID_FILE"
|
|
182
|
+
)
|
|
183
|
+
# Disown the background process so it outlives this script.
|
|
184
|
+
disown "$(cat "$PID_FILE" 2>/dev/null || true)" 2>/dev/null || true
|
|
185
|
+
|
|
186
|
+
start_viewer_window "$LOG_FILE"
|
|
187
|
+
|
|
188
|
+
# Attach a log-tui watcher for compact event display (best-effort; non-blocking).
|
|
189
|
+
LOG_TUI="$(dirname "$0")/../shared/log-tui.mjs"
|
|
190
|
+
TAIL_PID=""
|
|
191
|
+
if [ -f "$LOG_TUI" ] && command -v node >/dev/null 2>&1 \
|
|
192
|
+
&& [ "${METAMASK_RECIPE_AUTO_HUD:-1}" != "0" ]; then
|
|
193
|
+
node "$LOG_TUI" watch \
|
|
194
|
+
--log "$LOG_FILE" \
|
|
195
|
+
--events "${RECIPE_LOG_EVENTS:-12}" \
|
|
196
|
+
--mode compact \
|
|
197
|
+
--label "Metro bundler" \
|
|
198
|
+
--success-pattern 'Dev server ready' &
|
|
199
|
+
TAIL_PID=$!
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
# Ready-poll: 90 × 1s = 90 s timeout.
|
|
203
|
+
READY=false
|
|
204
|
+
for _i in $(seq 1 90); do
|
|
205
|
+
if metro_ready; then
|
|
206
|
+
READY=true
|
|
207
|
+
break
|
|
208
|
+
fi
|
|
209
|
+
sleep 1
|
|
210
|
+
done
|
|
211
|
+
|
|
212
|
+
[ -n "$TAIL_PID" ] && { kill "$TAIL_PID" 2>/dev/null; wait "$TAIL_PID" 2>/dev/null || true; }
|
|
213
|
+
|
|
214
|
+
if [ "$READY" = true ]; then
|
|
215
|
+
printf 'Metro ready on port %s\n' "$PORT" >&2
|
|
216
|
+
printf ' Next: mm-harness logs (tail Metro)\n' >&2
|
|
217
|
+
exit 0
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
# Failure: dump log events for diagnosis.
|
|
221
|
+
if [ -f "$LOG_TUI" ] && command -v node >/dev/null 2>&1; then
|
|
222
|
+
node "$LOG_TUI" events --log "$LOG_FILE" --events 20 >&2 || true
|
|
223
|
+
else
|
|
224
|
+
tail -40 "$LOG_FILE" >&2 || true
|
|
225
|
+
fi
|
|
226
|
+
printf 'start-metro: Metro did not become ready on port %s within 90s\n' "$PORT" >&2
|
|
227
|
+
printf ' Next: check %s for errors, or run mm-harness logs\n' "$LOG_FILE" >&2
|
|
228
|
+
exit 1
|
|
@@ -58,12 +58,12 @@ esac
|
|
|
58
58
|
|
|
59
59
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
60
60
|
# shellcheck disable=SC1091
|
|
61
|
-
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../../
|
|
61
|
+
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../../adapters/shared/harness-path.sh" "$SCRIPT_DIR/../shared/harness-path.sh"; do
|
|
62
62
|
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
63
63
|
done
|
|
64
64
|
unset _hp
|
|
65
65
|
if ! command -v harness_root >/dev/null 2>&1; then
|
|
66
|
-
echo "mobile verify: shared lib
|
|
66
|
+
echo "mobile verify: shared lib adapters/shared/harness-path.sh not found; reinstall the runner." >&2
|
|
67
67
|
exit 1
|
|
68
68
|
fi
|
|
69
69
|
TARGET="$(cd "$TARGET" && pwd)"
|
|
@@ -71,7 +71,7 @@ RUNTIME_DIR="$(recipe_runtime_dir)"
|
|
|
71
71
|
HARNESS_ROOT="$(harness_root)"
|
|
72
72
|
HARNESS_REL="$HARNESS_ROOT/mobile"
|
|
73
73
|
HARNESS_DIR="$(harness_dir "$TARGET" mobile)"
|
|
74
|
-
RUNNER_BIN="$HARNESS_DIR/runner/bin/
|
|
74
|
+
RUNNER_BIN="$HARNESS_DIR/runner/bin/mm-harness"
|
|
75
75
|
ARTIFACTS="${ARTIFACTS:-$HARNESS_DIR/verify/$(date -u +%Y%m%dT%H%M%SZ)}"
|
|
76
76
|
mkdir -p "$ARTIFACTS/logs"
|
|
77
77
|
|
|
@@ -221,7 +221,7 @@ check_file() {
|
|
|
221
221
|
|
|
222
222
|
check_file "$HARNESS_REL/manifest.json"
|
|
223
223
|
check_file "$HARNESS_REL/action-manifest.json"
|
|
224
|
-
check_file "$HARNESS_REL/runner/bin/
|
|
224
|
+
check_file "$HARNESS_REL/runner/bin/mm-harness"
|
|
225
225
|
check_file "package.json"
|
|
226
226
|
check_file "app/dev-tools/AgenticService/AgenticService.ts"
|
|
227
227
|
|
|
@@ -263,7 +263,7 @@ if (!runnerDir) {
|
|
|
263
263
|
process.stdout.write(JSON.stringify({ name, status: 'warn', detail: 'runner source unavailable; overlay freshness compare skipped' }));
|
|
264
264
|
process.exit(0);
|
|
265
265
|
}
|
|
266
|
-
const overlayDir = path.join(runnerDir, '
|
|
266
|
+
const overlayDir = path.join(runnerDir, 'adapters', 'mobile', 'overlay', 'app', 'core', 'AgenticService');
|
|
267
267
|
let checked = 0;
|
|
268
268
|
const drifted = [];
|
|
269
269
|
const missing = [];
|
|
@@ -289,7 +289,7 @@ if (checked === 0) {
|
|
|
289
289
|
const parts = [];
|
|
290
290
|
if (drifted.length) parts.push('behind runner: ' + drifted.join(', '));
|
|
291
291
|
if (missing.length) parts.push('absent in repo: ' + missing.join(', '));
|
|
292
|
-
process.stdout.write(JSON.stringify({ name, status: 'warn', detail: parts.join('; ') + ' — rerun
|
|
292
|
+
process.stdout.write(JSON.stringify({ name, status: 'warn', detail: parts.join('; ') + ' — rerun mm-harness install --force-overlay or recipe sync to refresh the in-repo HUD/AgenticService from the runner' }));
|
|
293
293
|
} else {
|
|
294
294
|
process.stdout.write(JSON.stringify({ name, status: 'pass' }));
|
|
295
295
|
}
|