@deeeed/metamask-harness 0.2.0 → 0.3.1
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 +33 -0
- package/README.md +47 -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 +260 -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 +37 -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 +105 -5
- 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 +48 -40
- package/src/commands/debug.ts +63 -0
- package/src/commands/fixtures.ts +193 -0
- package/{runner/src → src}/commands/launch.ts +200 -54
- package/src/commands/logs.ts +83 -0
- package/{runner/src → src}/commands/shared.ts +40 -30
- package/src/commands/update.ts +316 -0
- package/{runner/src → src}/harness.ts +119 -16
- package/{runner/src → src}/heal-bounds.ts +20 -1
- package/src/index.ts +15 -0
- package/{runner/src → src}/live-adapter-contract.ts +1 -1
- package/{runner/src → src}/mm-harness-cli.ts +64 -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}/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
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# live.sh — mobile launch-then-verify chaining for one live slot run
|
|
3
|
-
#
|
|
4
|
-
# Purpose:
|
|
5
|
-
# Runs launch.sh then verify.sh (verify with --no-auto-start; launch owns
|
|
6
|
-
# startup) under a timestamped artifact dir and aggregates both results.
|
|
7
|
-
#
|
|
8
|
-
# Inputs (flags / env):
|
|
9
|
-
# --target <metamask-mobile> (default $PWD)
|
|
10
|
-
# --platform ios|android (default ios)
|
|
11
|
-
# --preflight-mode|--mode fast|auto|default|rebuild-native|clean
|
|
12
|
-
# (env RECIPE_HARNESS_MOBILE_PREFLIGHT_MODE, default fast)
|
|
13
|
-
# --artifacts-dir <dir> (default <harness>/live/<UTC>)
|
|
14
|
-
# --wallet-setup|--no-wallet-setup (default auto), --wallet-fixture <json>
|
|
15
|
-
#
|
|
16
|
-
# Outputs:
|
|
17
|
-
# <artifacts>/summary.json (adapter/action/status, launch/verify exit codes
|
|
18
|
-
# + child summary paths, easyCommand), <artifacts>/{launch,verify}/.
|
|
19
|
-
# Exit 0 — launch and verify both passed; 1 — either failed; 2 — bad args.
|
|
20
|
-
#
|
|
21
|
-
# Never touches: product source files; anything outside the target's harness
|
|
22
|
-
# dir and the artifacts dir.
|
|
23
|
-
set -euo pipefail
|
|
24
|
-
|
|
25
|
-
TARGET="$PWD"
|
|
26
|
-
PLATFORM="ios"
|
|
27
|
-
PREFLIGHT_MODE="${RECIPE_HARNESS_MOBILE_PREFLIGHT_MODE:-fast}"
|
|
28
|
-
ARTIFACTS=""
|
|
29
|
-
WALLET_SETUP="auto"
|
|
30
|
-
WALLET_FIXTURE=""
|
|
31
|
-
while [ "$#" -gt 0 ]; do
|
|
32
|
-
case "$1" in
|
|
33
|
-
--target) TARGET="$2"; shift 2 ;;
|
|
34
|
-
--platform) PLATFORM="$2"; shift 2 ;;
|
|
35
|
-
--preflight-mode|--mode) PREFLIGHT_MODE="$2"; shift 2 ;;
|
|
36
|
-
--artifacts-dir) ARTIFACTS="$2"; shift 2 ;;
|
|
37
|
-
--wallet-setup) WALLET_SETUP="true"; shift ;;
|
|
38
|
-
--no-wallet-setup) WALLET_SETUP="false"; shift ;;
|
|
39
|
-
--wallet-fixture) WALLET_FIXTURE="$2"; shift 2 ;;
|
|
40
|
-
-h|--help) echo "Usage: live.sh [--target <metamask-mobile>] [--platform ios|android] [--preflight-mode fast|auto|default|rebuild-native|clean] [--artifacts-dir <dir>] [--wallet-setup|--no-wallet-setup]"; exit 0 ;;
|
|
41
|
-
*) echo "Unknown arg: $1" >&2; exit 2 ;;
|
|
42
|
-
esac
|
|
43
|
-
done
|
|
44
|
-
|
|
45
|
-
case "$PLATFORM" in ios|android) ;; *) echo "Unknown --platform: $PLATFORM" >&2; exit 2 ;; esac
|
|
46
|
-
case "$PREFLIGHT_MODE" in fast|auto|default|rebuild-native|clean) ;; *) echo "Unknown --preflight-mode: $PREFLIGHT_MODE" >&2; exit 2 ;; esac
|
|
47
|
-
|
|
48
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
49
|
-
# shellcheck disable=SC1091
|
|
50
|
-
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../lib/harness-path.sh"; do
|
|
51
|
-
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
52
|
-
done
|
|
53
|
-
unset _hp
|
|
54
|
-
if ! command -v harness_root >/dev/null 2>&1; then
|
|
55
|
-
echo "mm-harness: shared lib orchestration/lib/harness-path.sh not found; reinstall the runner." >&2
|
|
56
|
-
exit 1
|
|
57
|
-
fi
|
|
58
|
-
# verify.sh is a recipe-tree feature: co-located in installed copies, under
|
|
59
|
-
# runner/mobile in a repo checkout.
|
|
60
|
-
VERIFY_SH=""
|
|
61
|
-
for _v in "$SCRIPT_DIR/verify.sh" "$SCRIPT_DIR/../../runner/mobile/verify.sh"; do
|
|
62
|
-
[ -f "$_v" ] && { VERIFY_SH="$_v"; break; }
|
|
63
|
-
done
|
|
64
|
-
unset _v
|
|
65
|
-
if [ -z "$VERIFY_SH" ]; then
|
|
66
|
-
echo "mm-harness: mobile verify.sh not found next to $SCRIPT_DIR; reinstall the runner." >&2
|
|
67
|
-
exit 1
|
|
68
|
-
fi
|
|
69
|
-
TARGET="$(cd "$TARGET" && pwd)"
|
|
70
|
-
WALLET_FIXTURE="${WALLET_FIXTURE:-$(recipe_runtime_dir)/wallet-fixture.json}"
|
|
71
|
-
ARTIFACTS="${ARTIFACTS:-$(harness_dir "$TARGET" mobile)/live/$(date -u +%Y%m%dT%H%M%SZ)}"
|
|
72
|
-
mkdir -p "$ARTIFACTS"
|
|
73
|
-
|
|
74
|
-
launch_args=(--target "$TARGET" --platform "$PLATFORM" --preflight-mode "$PREFLIGHT_MODE" --artifacts-dir "$ARTIFACTS/launch")
|
|
75
|
-
case "$WALLET_SETUP" in
|
|
76
|
-
true) launch_args+=(--wallet-setup) ;;
|
|
77
|
-
false) launch_args+=(--no-wallet-setup) ;;
|
|
78
|
-
esac
|
|
79
|
-
launch_args+=(--wallet-fixture "$WALLET_FIXTURE")
|
|
80
|
-
|
|
81
|
-
echo "Mobile live validation command:"
|
|
82
|
-
echo " mm-harness launch $PLATFORM --verify"
|
|
83
|
-
echo "Launch artifacts: $ARTIFACTS/launch"
|
|
84
|
-
echo "Verify artifacts: $ARTIFACTS/verify"
|
|
85
|
-
|
|
86
|
-
set +e
|
|
87
|
-
"$SCRIPT_DIR/launch.sh" "${launch_args[@]}"
|
|
88
|
-
launch_status=$?
|
|
89
|
-
set -e
|
|
90
|
-
|
|
91
|
-
verify_status=1
|
|
92
|
-
if [ "$launch_status" -eq 0 ]; then
|
|
93
|
-
set +e
|
|
94
|
-
"$VERIFY_SH" --target "$TARGET" --platform "$PLATFORM" --preflight-mode "$PREFLIGHT_MODE" --no-auto-start --artifacts-dir "$ARTIFACTS/verify"
|
|
95
|
-
verify_status=$?
|
|
96
|
-
set -e
|
|
97
|
-
else
|
|
98
|
-
echo "Skipping Mobile live verify because launch failed; see $ARTIFACTS/launch/summary.json" >&2
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
TARGET_FOR_SUMMARY="$TARGET" ARTIFACTS_FOR_SUMMARY="$ARTIFACTS" PLATFORM_FOR_SUMMARY="$PLATFORM" MODE_FOR_SUMMARY="$PREFLIGHT_MODE" LAUNCH_STATUS="$launch_status" VERIFY_STATUS="$verify_status" node <<'NODE'
|
|
102
|
-
const fs = require('fs');
|
|
103
|
-
const path = require('path');
|
|
104
|
-
const artifacts = process.env.ARTIFACTS_FOR_SUMMARY;
|
|
105
|
-
const launchSummary = path.join(artifacts, 'launch', 'summary.json');
|
|
106
|
-
const verifySummary = path.join(artifacts, 'verify', 'summary.json');
|
|
107
|
-
const launchStatus = Number(process.env.LAUNCH_STATUS);
|
|
108
|
-
const verifyStatus = Number(process.env.VERIFY_STATUS);
|
|
109
|
-
fs.writeFileSync(path.join(artifacts, 'summary.json'), `${JSON.stringify({
|
|
110
|
-
adapter: 'mobile',
|
|
111
|
-
action: 'live',
|
|
112
|
-
status: launchStatus === 0 && verifyStatus === 0 ? 'pass' : 'fail',
|
|
113
|
-
target: process.env.TARGET_FOR_SUMMARY,
|
|
114
|
-
platform: process.env.PLATFORM_FOR_SUMMARY,
|
|
115
|
-
preflightMode: process.env.MODE_FOR_SUMMARY,
|
|
116
|
-
launch: { exitCode: launchStatus, summaryPath: fs.existsSync(launchSummary) ? launchSummary : null },
|
|
117
|
-
verify: { exitCode: verifyStatus, summaryPath: fs.existsSync(verifySummary) ? verifySummary : null },
|
|
118
|
-
easyCommand: `mm-harness launch ${process.env.PLATFORM_FOR_SUMMARY} --verify`,
|
|
119
|
-
note: 'Runs launch then live verify so a developer can validate app startup, runner-owned CDP bridge, screenshot capture, and tiny recipe control from one runner-owned command.',
|
|
120
|
-
generatedAt: new Date().toISOString(),
|
|
121
|
-
}, null, 2)}\n`);
|
|
122
|
-
NODE
|
|
123
|
-
|
|
124
|
-
echo "Mobile live validation summary: $ARTIFACTS/summary.json"
|
|
125
|
-
[ "$launch_status" -eq 0 ] && [ "$verify_status" -eq 0 ]
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
SOURCE="${BASH_SOURCE[0]}"
|
|
4
|
-
while [ -L "$SOURCE" ]; do
|
|
5
|
-
SOURCE_DIR="$(cd "$(dirname "$SOURCE")" && pwd -P)"
|
|
6
|
-
TARGET="$(readlink "$SOURCE")"
|
|
7
|
-
if [[ "$TARGET" == /* ]]; then
|
|
8
|
-
SOURCE="$TARGET"
|
|
9
|
-
else
|
|
10
|
-
SOURCE="$SOURCE_DIR/$TARGET"
|
|
11
|
-
fi
|
|
12
|
-
done
|
|
13
|
-
SCRIPT_DIR="$(cd "$(dirname "$SOURCE")" && pwd -P)"
|
|
14
|
-
# This script lives at <root>/orchestration/porcelain/; the runner root is two up.
|
|
15
|
-
RUNNER_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
16
|
-
|
|
17
|
-
ENSURE_DEPS="$RUNNER_DIR/orchestration/lib/ensure-runner-deps.sh"
|
|
18
|
-
if [ -f "$ENSURE_DEPS" ]; then
|
|
19
|
-
# shellcheck disable=SC1090
|
|
20
|
-
bash "$ENSURE_DEPS" "$RUNNER_DIR"
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
if [ "${1:-}" = "mobile" ]; then
|
|
24
|
-
shift
|
|
25
|
-
exec "$RUNNER_DIR/bin/mm-recipe" "$@"
|
|
26
|
-
fi
|
|
27
|
-
if [ "${1:-}" = "extension" ]; then
|
|
28
|
-
shift
|
|
29
|
-
exec "$RUNNER_DIR/bin/mme-recipe" "$@"
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
find_protocol_root() {
|
|
33
|
-
local start="$1"
|
|
34
|
-
local dir
|
|
35
|
-
dir="$(cd "$start" && pwd -P)"
|
|
36
|
-
while [ "$dir" != "/" ]; do
|
|
37
|
-
if [ -f "$dir/packages/recipe-harness/package.json" ] && [ -f "$dir/packages/protocol/package.json" ]; then
|
|
38
|
-
printf '%s\n' "$dir"
|
|
39
|
-
return 0
|
|
40
|
-
fi
|
|
41
|
-
if [ -f "$dir/farmslot/packages/recipe-harness/package.json" ] && [ -f "$dir/farmslot/packages/protocol/package.json" ]; then
|
|
42
|
-
printf '%s\n' "$dir/farmslot"
|
|
43
|
-
return 0
|
|
44
|
-
fi
|
|
45
|
-
dir="$(dirname "$dir")"
|
|
46
|
-
done
|
|
47
|
-
return 1
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
node_can_run_source_typescript() {
|
|
51
|
-
# Node refuses type-stripping for files under node_modules (ERR_UNSUPPORTED_NODE_
|
|
52
|
-
# MODULES_TYPE_STRIPPING). When this runner is installed as a dependency, cli.ts
|
|
53
|
-
# lives under node_modules and cannot run under plain node — a /tmp probe would be a
|
|
54
|
-
# false positive. Skip the node-source path in that case and fall through to dist/tsx.
|
|
55
|
-
case "$RUNNER_DIR/" in
|
|
56
|
-
*/node_modules/*) return 1 ;;
|
|
57
|
-
esac
|
|
58
|
-
local probe_dir probe_file
|
|
59
|
-
probe_dir="$(mktemp -d "${TMPDIR:-/tmp}/metamask-recipe-node-ts.XXXXXX")"
|
|
60
|
-
probe_file="$probe_dir/probe.ts"
|
|
61
|
-
printf 'const answer: number = 42; if (answer !== 42) process.exit(1);\n' > "$probe_file"
|
|
62
|
-
if ! node --no-warnings "$probe_file" >/dev/null 2>&1; then
|
|
63
|
-
rm -rf "$probe_dir"
|
|
64
|
-
return 1
|
|
65
|
-
fi
|
|
66
|
-
rm -rf "$probe_dir"
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if [ -f "$RUNNER_DIR/dist/cli.js" ]; then
|
|
70
|
-
exec node "$RUNNER_DIR/dist/cli.js" "$@"
|
|
71
|
-
fi
|
|
72
|
-
|
|
73
|
-
TSX_BIN="${TSX_BIN:-$RUNNER_DIR/node_modules/.bin/tsx}"
|
|
74
|
-
if [ ! -x "$TSX_BIN" ] && [ -x "$RUNNER_DIR/../../.bin/tsx" ]; then
|
|
75
|
-
TSX_BIN="$RUNNER_DIR/../../.bin/tsx"
|
|
76
|
-
fi
|
|
77
|
-
if [ ! -x "$TSX_BIN" ]; then
|
|
78
|
-
if [ -z "${FARMSLOT_ROOT:-}" ] && [ -f "$RUNNER_DIR/.farmslot-root" ]; then
|
|
79
|
-
FARMSLOT_ROOT="$(cat "$RUNNER_DIR/.farmslot-root")"
|
|
80
|
-
fi
|
|
81
|
-
if [ -z "${FARMSLOT_ROOT:-}" ]; then
|
|
82
|
-
FARMSLOT_ROOT="$(find_protocol_root "$RUNNER_DIR" || find_protocol_root "$PWD" || true)"
|
|
83
|
-
fi
|
|
84
|
-
if [ -n "${FARMSLOT_ROOT:-}" ]; then
|
|
85
|
-
FARMSLOT_ROOT="$(cd "$FARMSLOT_ROOT" && pwd -P)"
|
|
86
|
-
TSX_BIN="$FARMSLOT_ROOT/node_modules/.bin/tsx"
|
|
87
|
-
fi
|
|
88
|
-
fi
|
|
89
|
-
|
|
90
|
-
if node_can_run_source_typescript; then
|
|
91
|
-
exec node --no-warnings "$RUNNER_DIR/runner/src/cli.ts" "$@"
|
|
92
|
-
fi
|
|
93
|
-
|
|
94
|
-
if [ -x "$TSX_BIN" ]; then
|
|
95
|
-
exec "$TSX_BIN" "$RUNNER_DIR/runner/src/cli.ts" "$@"
|
|
96
|
-
fi
|
|
97
|
-
|
|
98
|
-
echo "metamask-recipe source checkout requires dist/cli.js, Node.js TypeScript type stripping, or a local tsx binary. Install dependencies normally, or set TSX_BIN/FARMSLOT_ROOT for local protocol co-development." >&2
|
|
99
|
-
exit 1
|