@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0 - 2026-07-03
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Porcelain layer eliminated: the legacy `mm-recipe`/`mme-recipe`/`metamask-recipe` bins are gone; launch/logs/debug/fixtures compose the adapter scripts directly in TypeScript. Repository reorganized into `src/` (all TS), `adapters/` (per-platform runtime glue), `library/` (recipe/action/flow vocabulary).
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- Extension `launch` opens the app directly (composes `live.sh`) instead of a retired command.
|
|
10
|
+
- Mobile `cleanup` resilient to a stale runner-source path.
|
|
11
|
+
- Core run teaches the correct next step when no account is set.
|
|
12
|
+
- Resolved CodeQL alerts (insecure temp dir, file-access-to-http).
|
|
13
|
+
|
|
14
|
+
## Unreleased
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **Repository reorganized into `src/`, `adapters/`, `library/` domains**: all TypeScript now lives under `src/` (shared CLI/core plus typed per-adapter logic in `src/adapters/<adapter>/`); everything that executes against or is injected into the app runtime lives under `adapters/` (`adapters/<adapter>/` per-app glue, `adapters/shared/` cross-adapter OS-glue, `adapters/porcelain/` composed entrypoints, `adapters/*/overlay/` the only injected payload); `library/` holds composable vocabulary only. The `runner/` and `orchestration/` trees no longer exist. The surface doctor moved to `scripts/adapter-surface-doctor.mjs` with its index at `adapters/manifest.json`. Placement rules (R1–R11) are documented in `AGENTS.md`. This is a path-only reorganization; runtime behavior is unchanged.
|
|
19
|
+
|
|
3
20
|
## 0.2.0 - 2026-07-03
|
|
4
21
|
|
|
5
22
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# MetaMask Recipe Runner — `mm-harness`
|
|
2
2
|
|
|
3
|
+
Architecture: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
|
|
4
|
+
|
|
3
5
|
**`mm-harness` is built for the agent but easy for the human to use and
|
|
4
6
|
understand.** It is the MetaMask recipe harness: one front door to launch the app,
|
|
5
7
|
prove behavior with recipes, and manage the per-checkout runtime overlay. It is a
|
|
@@ -26,8 +28,7 @@ completions (zsh + bash) for commands, targets, and flags.
|
|
|
26
28
|
Naming: **"harness" is the tool** (`mm-harness`) and the generic engine package
|
|
27
29
|
(`@farmslot/recipe-harness`); the files it installs into a checkout are the
|
|
28
30
|
**runtime overlay**. Read [MENTAL-MODEL.md](docs/MENTAL-MODEL.md) first (the
|
|
29
|
-
before→after map), then [CLI-SPEC.md](docs/CLI-SPEC.md) for the full contract
|
|
30
|
-
([harness-cli.md](docs/harness-cli.md) is a short pointer to it).
|
|
31
|
+
before→after map), then [CLI-SPEC.md](docs/CLI-SPEC.md) for the full contract.
|
|
31
32
|
|
|
32
33
|
One package, two responsibilities:
|
|
33
34
|
|
|
@@ -60,8 +61,8 @@ mm-harness run # runner/proof: actions execute and evidence is saved
|
|
|
60
61
|
```
|
|
61
62
|
|
|
62
63
|
Do not mix those layers. library/ = what recipes ARE (recipes, actions,
|
|
63
|
-
manifests — the content).
|
|
64
|
-
|
|
64
|
+
manifests — the content). src/ = what EXECUTES them (TypeScript CLI/engine glue,
|
|
65
|
+
typed adapters). adapters/ = what CONTROLS the app and its instances (start,
|
|
65
66
|
windows, wallet state, health, ports, parallel).
|
|
66
67
|
|
|
67
68
|
## Useful commands
|
|
@@ -91,20 +92,22 @@ to tune the compact log view during launch and Metro/webpack startup.
|
|
|
91
92
|
## Layout
|
|
92
93
|
|
|
93
94
|
```text
|
|
94
|
-
bin/
|
|
95
|
-
|
|
96
|
-
per-
|
|
97
|
-
|
|
95
|
+
bin/ the mm-harness entrypoint
|
|
96
|
+
src/ what EXECUTES recipes: TypeScript CLI/engine glue +
|
|
97
|
+
typed per-adapter logic (src/adapters/)
|
|
98
|
+
adapters/ what CONTROLS the app and its instances: launch/live/
|
|
98
99
|
watch/windows/wallet state/health/inject/cleanup per
|
|
99
|
-
platform, shared
|
|
100
|
+
platform, shared glue, porcelain, overlay payload +
|
|
101
|
+
manifest.json
|
|
100
102
|
library/ what recipes ARE: recipes/ (recipe JSONs), actions/
|
|
101
103
|
(per-platform implementations), manifests/ (capability)
|
|
102
|
-
scripts/ dev tooling (yarn check, local farmslot link, e2e
|
|
104
|
+
scripts/ dev tooling (yarn check, local farmslot link, e2e
|
|
105
|
+
validation, adapter-surface-doctor)
|
|
103
106
|
docs/ details when this README is not enough
|
|
104
107
|
```
|
|
105
108
|
|
|
106
109
|
Defaults for installed harness/runtime paths live in
|
|
107
|
-
`
|
|
110
|
+
`adapters/shared/path-defaults.json`.
|
|
108
111
|
|
|
109
112
|
## Runtime-readiness ownership
|
|
110
113
|
|
|
@@ -114,10 +117,10 @@ Generic readiness mechanics live in `@farmslot/recipe-harness` (0.3+):
|
|
|
114
117
|
- `@farmslot/recipe-harness/runtime/log-analysis` — bundle-log boundaries, unresolved-module scoping
|
|
115
118
|
- `@farmslot/recipe-harness/runtime/metro-probe` — Metro `/status` reachability
|
|
116
119
|
|
|
117
|
-
This repo adds **MetaMask adapters only**: `
|
|
118
|
-
`
|
|
119
|
-
and shell launch in `
|
|
120
|
-
primitives into `
|
|
120
|
+
This repo adds **MetaMask adapters only**: `adapters/mobile/deps-markers.ts`,
|
|
121
|
+
`adapters/mobile/runtime-decision.ts`, `adapters/extension/runtime-decision.ts`,
|
|
122
|
+
and shell launch in `adapters/porcelain/mm-recipe` / `adapters/porcelain/mme-recipe`. Do not re-copy harness
|
|
123
|
+
primitives into `adapters/shared/`. CI installs harness from npm — publish
|
|
121
124
|
`@farmslot/recipe-harness` before bumping the dependency here.
|
|
122
125
|
|
|
123
126
|
## Runtime notes
|
|
@@ -133,8 +136,8 @@ primitives into `orchestration/lib/`. CI installs harness from npm — publish
|
|
|
133
136
|
|
|
134
137
|
```bash
|
|
135
138
|
yarn check
|
|
136
|
-
bash -n bin/mm-harness
|
|
137
|
-
node --check
|
|
139
|
+
bash -n bin/mm-harness adapters/porcelain/{metamask-recipe,mm-recipe,mme-recipe} adapters/{mobile,extension,core}/*.sh
|
|
140
|
+
node --check adapters/extension/inject.mjs adapters/extension/cleanup.mjs adapters/extension/readiness.mjs adapters/extension/launch-browser.cjs adapters/shared/open-debug.mjs adapters/shared/cli-home.mjs adapters/shared/log-tui.mjs adapters/shared/progress.mjs adapters/shared/recipe-paths.mjs scripts/check.mjs
|
|
138
141
|
```
|
|
139
142
|
|
|
140
143
|
More detail: [Architecture](docs/architecture.md), [Package boundaries](docs/package-boundaries.md), [Runtime file conventions](docs/runtime-file-conventions.md).
|
|
@@ -23,12 +23,12 @@ done
|
|
|
23
23
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
24
24
|
TARGET="$(cd "$TARGET" && pwd)"
|
|
25
25
|
# shellcheck disable=SC1091
|
|
26
|
-
for _hp in "$SCRIPT_DIR/../
|
|
26
|
+
for _hp in "$SCRIPT_DIR/../shared/harness-path.sh"; do
|
|
27
27
|
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
28
28
|
done
|
|
29
29
|
unset _hp
|
|
30
30
|
if ! command -v harness_root >/dev/null 2>&1; then
|
|
31
|
-
echo "mm-harness: shared lib
|
|
31
|
+
echo "mm-harness: shared lib adapters/shared/harness-path.sh not found; reinstall the runner." >&2
|
|
32
32
|
exit 1
|
|
33
33
|
fi
|
|
34
34
|
HARNESS_DIR="$(harness_dir "$TARGET" core)"
|
|
@@ -27,12 +27,12 @@ done
|
|
|
27
27
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
28
|
RUNNER_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd -P)"
|
|
29
29
|
# shellcheck disable=SC1091
|
|
30
|
-
for _hp in "$SCRIPT_DIR/../
|
|
30
|
+
for _hp in "$SCRIPT_DIR/../shared/harness-path.sh"; do
|
|
31
31
|
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
32
32
|
done
|
|
33
33
|
unset _hp
|
|
34
34
|
if ! command -v harness_root >/dev/null 2>&1; then
|
|
35
|
-
echo "mm-harness: shared lib
|
|
35
|
+
echo "mm-harness: shared lib adapters/shared/harness-path.sh not found; reinstall the runner." >&2
|
|
36
36
|
exit 1
|
|
37
37
|
fi
|
|
38
38
|
TARGET="$(cd "$TARGET" && pwd)"
|
|
@@ -81,7 +81,7 @@ install_v1_runner_assets() {
|
|
|
81
81
|
# break the generated wrapper or inject at runtime.
|
|
82
82
|
local runner_protocol_root_q runner_exec_q
|
|
83
83
|
runner_protocol_root_q="$(printf '%q' "$METAMASK_RUNNER_PROTOCOL_ROOT")"
|
|
84
|
-
runner_exec_q="$(printf '%q' "$METAMASK_RUNNER_DIR/
|
|
84
|
+
runner_exec_q="$(printf '%q' "$METAMASK_RUNNER_DIR/bin/mm-harness")"
|
|
85
85
|
{
|
|
86
86
|
printf '%s\n' '#!/usr/bin/env bash'
|
|
87
87
|
printf '%s\n' 'set -euo pipefail'
|
|
@@ -89,8 +89,8 @@ install_v1_runner_assets() {
|
|
|
89
89
|
printf 'export FARMSLOT_ROOT=${FARMSLOT_ROOT:-%s}\n' "$runner_protocol_root_q"
|
|
90
90
|
fi
|
|
91
91
|
printf 'exec %s "$@"\n' "$runner_exec_q"
|
|
92
|
-
} > "$HARNESS_DIR/runner/bin/
|
|
93
|
-
chmod +x "$HARNESS_DIR/runner/bin/
|
|
92
|
+
} > "$HARNESS_DIR/runner/bin/mm-harness"
|
|
93
|
+
chmod +x "$HARNESS_DIR/runner/bin/mm-harness"
|
|
94
94
|
if [ -n "$METAMASK_RUNNER_PROTOCOL_ROOT" ]; then
|
|
95
95
|
printf '%s\n' "$METAMASK_RUNNER_PROTOCOL_ROOT" > "$HARNESS_DIR/runner/.farmslot-root"
|
|
96
96
|
fi
|
|
@@ -113,7 +113,7 @@ install_v1_runner_assets() {
|
|
|
113
113
|
if [ -f "$METAMASK_RUNNER_DIR/library/library.json" ]; then
|
|
114
114
|
cp "$METAMASK_RUNNER_DIR/library/library.json" "$HARNESS_DIR/runner/library.json"
|
|
115
115
|
fi
|
|
116
|
-
if [ ! -x "$HARNESS_DIR/runner/bin/
|
|
116
|
+
if [ ! -x "$HARNESS_DIR/runner/bin/mm-harness" ]; then
|
|
117
117
|
echo "Refusing core recipe harness install: failed to make runner executable." >&2
|
|
118
118
|
return 1
|
|
119
119
|
fi
|
|
@@ -121,7 +121,7 @@ install_v1_runner_assets() {
|
|
|
121
121
|
|
|
122
122
|
install_v1_runner_assets
|
|
123
123
|
|
|
124
|
-
ENSURE_DEPS="$SCRIPT_DIR/../
|
|
124
|
+
ENSURE_DEPS="$SCRIPT_DIR/../shared/ensure-runner-deps.sh"
|
|
125
125
|
if [ -f "$ENSURE_DEPS" ]; then
|
|
126
126
|
bash "$ENSURE_DEPS" "$RUNNER_DIR"
|
|
127
127
|
fi
|
|
@@ -142,7 +142,7 @@ node -e '
|
|
|
142
142
|
target,
|
|
143
143
|
protocolVersion: "v1",
|
|
144
144
|
actionManifestPath: harnessRel + "/action-manifest.json",
|
|
145
|
-
runnerEntrypoint: harnessRel + "/runner/bin/
|
|
145
|
+
runnerEntrypoint: harnessRel + "/runner/bin/mm-harness",
|
|
146
146
|
runtimeHelpers: {},
|
|
147
147
|
installedPaths: [harnessRel + "/runner"],
|
|
148
148
|
patchedFiles: [],
|
|
@@ -18,7 +18,7 @@ import fs from 'node:fs';
|
|
|
18
18
|
import path from 'node:path';
|
|
19
19
|
import { spawnSync } from 'node:child_process';
|
|
20
20
|
import process from 'node:process';
|
|
21
|
-
import { recipeHarnessRoot } from '
|
|
21
|
+
import { recipeHarnessRoot } from '../../src/paths.ts';
|
|
22
22
|
|
|
23
23
|
function usage() { console.error('Usage: cleanup-extension-harness.mjs [--target <metamask-extension>]'); }
|
|
24
24
|
let target = process.cwd();
|
|
@@ -62,6 +62,9 @@ const attached = new Map();
|
|
|
62
62
|
// before ever connecting, so a dead/non-debuggable target is not retried every poll).
|
|
63
63
|
const cooldown = new Map();
|
|
64
64
|
|
|
65
|
+
// Writes formatted console-event strings (never raw HTTP response bodies) to
|
|
66
|
+
// stdout and optionally to a caller-supplied log file. The source is the local
|
|
67
|
+
// Chrome CDP WebSocket (127.0.0.1:<cdpPort>) — a trusted-local endpoint.
|
|
65
68
|
function out(line) {
|
|
66
69
|
process.stdout.write(`${line}\n`);
|
|
67
70
|
if (args.log) appendFileSync(args.log, `${line}\n`);
|
|
@@ -58,12 +58,12 @@ done
|
|
|
58
58
|
# Script lives at <repo>/<runtime_dir>/reopen-browser.sh
|
|
59
59
|
SCRIPT_DIR="$(cd "$(dirname "$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/../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 "reopen-browser: shared lib
|
|
66
|
+
echo "reopen-browser: shared lib adapters/shared/harness-path.sh missing; reinstall the harness." >&2
|
|
67
67
|
exit 1
|
|
68
68
|
fi
|
|
69
69
|
if [[ -z "$RUNTIME_DIR" ]]; then
|
|
@@ -118,7 +118,7 @@ WALLET_FIXTURE="${AGENT_DIR}/wallet-fixture.json"
|
|
|
118
118
|
# single source of truth (deterministic id from the loaded dist's manifest key).
|
|
119
119
|
# Honor the configured recipe harness root.
|
|
120
120
|
HARNESS_ROOT="$(harness_root)"
|
|
121
|
-
RUNNER_BIN="${REPO}/${HARNESS_ROOT}/extension/runner/bin/
|
|
121
|
+
RUNNER_BIN="${REPO}/${HARNESS_ROOT}/extension/runner/bin/mm-harness"
|
|
122
122
|
|
|
123
123
|
# --- Preflight checks ---
|
|
124
124
|
if [ ! -f "${EXTENSION}/manifest.json" ]; then
|
|
@@ -134,7 +134,7 @@ fi
|
|
|
134
134
|
|
|
135
135
|
if [ ! -f "${PROFILE}/Default/Preferences" ]; then
|
|
136
136
|
echo "FAIL: existing browser profile not found at ${PROFILE}"
|
|
137
|
-
echo " Reopen only reuses an already-prepared profile. Run:
|
|
137
|
+
echo " Reopen only reuses an already-prepared profile. Run: mm-harness runtime-launch --adapter extension --target ${REPO} --cdp-port ${CDP_PORT} --chrome-user-data-dir ${PROFILE} --json"
|
|
138
138
|
exit 1
|
|
139
139
|
fi
|
|
140
140
|
|
|
@@ -23,7 +23,7 @@ import fs from 'node:fs';
|
|
|
23
23
|
import path from 'node:path';
|
|
24
24
|
import { spawnSync } from 'node:child_process';
|
|
25
25
|
import process from 'node:process';
|
|
26
|
-
import { recipeHarnessRoot } from '
|
|
26
|
+
import { recipeHarnessRoot } from '../../src/paths.ts';
|
|
27
27
|
|
|
28
28
|
function usage() {
|
|
29
29
|
console.error('Usage: inject-extension-harness.mjs [--target <metamask-extension>] [--no-git-exclude]');
|
|
@@ -72,9 +72,9 @@ const delegate = [
|
|
|
72
72
|
'#!/usr/bin/env bash',
|
|
73
73
|
'set -euo pipefail',
|
|
74
74
|
protocolRoot ? `export FARMSLOT_ROOT=\${FARMSLOT_ROOT:-${shellQuote(protocolRoot)}}` : null,
|
|
75
|
-
`exec ${shellQuote(path.join(runnerDir, '
|
|
75
|
+
`exec ${shellQuote(path.join(runnerDir, 'bin/mm-harness'))} "$@"`,
|
|
76
76
|
].filter(Boolean).join('\n') + '\n';
|
|
77
|
-
fs.writeFileSync(path.join(harnessDir, 'runner/bin/
|
|
77
|
+
fs.writeFileSync(path.join(harnessDir, 'runner/bin/mm-harness'), delegate, { mode: 0o755 });
|
|
78
78
|
if (protocolRoot) fs.writeFileSync(path.join(harnessDir, 'runner/.farmslot-root'), `${protocolRoot}\n`);
|
|
79
79
|
fs.writeFileSync(path.join(harnessDir, 'runner/.runner-source'), `${runnerDir}\n`);
|
|
80
80
|
copyFile(path.join(runnerDir, 'library/manifests/mobile.action-manifest.json'), path.join(harnessDir, 'runner/manifests/mobile.action-manifest.json'));
|
|
@@ -89,36 +89,32 @@ copyDir(path.join(runnerDir, 'library/flows'), path.join(harnessDir, 'runner/flo
|
|
|
89
89
|
// Installed-layout back-compat (INTENTIONAL): targets keep a flat
|
|
90
90
|
// <harness>/scripts/ subtree assembled from the runner trees, so installed
|
|
91
91
|
// consumers are unaffected by runner-repo layout changes.
|
|
92
|
-
copyFile(path.join(runnerDir, '
|
|
92
|
+
copyFile(path.join(runnerDir, 'adapters/extension/launch-browser.cjs'), path.join(harnessDir, 'scripts/launch-browser.cjs'));
|
|
93
93
|
// installed back-compat alias: callers of the pre-rename installed name
|
|
94
|
-
copyFile(path.join(runnerDir, '
|
|
95
|
-
copyFile(path.join(runnerDir, '
|
|
96
|
-
copyFile(path.join(runnerDir, '
|
|
97
|
-
copyFile(path.join(runnerDir, '
|
|
98
|
-
copyFile(path.join(runnerDir, '
|
|
99
|
-
copyFile(path.join(runnerDir, '
|
|
100
|
-
copyFile(path.join(runnerDir, '
|
|
101
|
-
copyFile(path.join(runnerDir, '
|
|
102
|
-
copyFile(path.join(runnerDir, '
|
|
103
|
-
copyFile(path.join(runnerDir, '
|
|
104
|
-
copyFile(path.join(runnerDir, '
|
|
105
|
-
copyFile(path.join(runnerDir, '
|
|
106
|
-
copyFile(path.join(runnerDir, '
|
|
107
|
-
copyFile(path.join(runnerDir, '
|
|
108
|
-
copyFile(path.join(runnerDir, '
|
|
109
|
-
copyFile(path.join(runnerDir, '
|
|
110
|
-
copyFile(path.join(runnerDir, '
|
|
111
|
-
copyFile(path.join(runnerDir, '
|
|
112
|
-
copyFile(path.join(runnerDir, '
|
|
113
|
-
copyFile(path.join(runnerDir, '
|
|
114
|
-
copyFile(path.join(runnerDir, 'orchestration/lib/cli-color.mjs'), path.join(harnessDir, 'scripts/lib/cli-color.mjs'));
|
|
115
|
-
copyFile(path.join(runnerDir, 'orchestration/lib/log-tui.mjs'), path.join(harnessDir, 'scripts/lib/log-tui.mjs'));
|
|
116
|
-
copyFile(path.join(runnerDir, 'orchestration/lib/progress.mjs'), path.join(harnessDir, 'scripts/lib/progress.mjs'));
|
|
117
|
-
copyFile(path.join(runnerDir, 'orchestration/lib/cli-version.mjs'), path.join(harnessDir, 'scripts/lib/cli-version.mjs'));
|
|
94
|
+
copyFile(path.join(runnerDir, 'adapters/extension/launch-browser.cjs'), path.join(harnessDir, 'scripts/launch-chrome-detached.cjs'));
|
|
95
|
+
copyFile(path.join(runnerDir, 'adapters/extension/console-tail.mjs'), path.join(harnessDir, 'scripts/console-tail.mjs'));
|
|
96
|
+
copyFile(path.join(runnerDir, 'adapters/extension/launch.sh'), path.join(harnessDir, 'scripts/launch.sh'));
|
|
97
|
+
copyFile(path.join(runnerDir, 'adapters/extension/live.sh'), path.join(harnessDir, 'scripts/live.sh'));
|
|
98
|
+
copyFile(path.join(runnerDir, 'adapters/extension/start-watch.sh'), path.join(harnessDir, 'scripts/start-watch.sh'));
|
|
99
|
+
copyFile(path.join(runnerDir, 'adapters/extension/snapshot-dist.sh'), path.join(harnessDir, 'scripts/snapshot-dist.sh'));
|
|
100
|
+
copyFile(path.join(runnerDir, 'adapters/extension/pin-remote-flags.cjs'), path.join(harnessDir, 'scripts/pin-remote-flags.cjs'));
|
|
101
|
+
copyFile(path.join(runnerDir, 'adapters/extension/seed-fixture.sh'), path.join(harnessDir, 'scripts/seed-fixture.sh'));
|
|
102
|
+
copyFile(path.join(runnerDir, 'adapters/extension/sidepanel-toggle.sh'), path.join(harnessDir, 'scripts/sidepanel-toggle.sh'));
|
|
103
|
+
copyFile(path.join(runnerDir, 'adapters/extension/readiness.mjs'), path.join(harnessDir, 'scripts/readiness.mjs'));
|
|
104
|
+
copyFile(path.join(runnerDir, 'adapters/extension/wallet-fixture-state.cjs'), path.join(harnessDir, 'scripts/wallet-fixture-state.cjs'));
|
|
105
|
+
copyFile(path.join(runnerDir, 'adapters/extension/verify.sh'), path.join(harnessDir, 'scripts/verify.sh'));
|
|
106
|
+
copyFile(path.join(runnerDir, 'adapters/extension/refresh-build.sh'), path.join(harnessDir, 'scripts/refresh-build.sh'));
|
|
107
|
+
copyFile(path.join(runnerDir, 'adapters/extension/ensure-browser.sh'), path.join(harnessDir, 'scripts/reopen-browser.sh'));
|
|
108
|
+
copyFile(path.join(runnerDir, 'adapters/shared/harness-path.sh'), path.join(harnessDir, 'scripts/lib/harness-path.sh'));
|
|
109
|
+
copyFile(path.join(runnerDir, 'adapters/shared/activate-repo-node.sh'), path.join(harnessDir, 'scripts/lib/activate-repo-node.sh'));
|
|
110
|
+
copyFile(path.join(runnerDir, 'adapters/shared/resolve-farmslot-ports.sh'), path.join(harnessDir, 'scripts/lib/resolve-farmslot-ports.sh'));
|
|
111
|
+
copyFile(path.join(runnerDir, 'adapters/shared/path-defaults.json'), path.join(harnessDir, 'scripts/lib/path-defaults.json'));
|
|
112
|
+
copyFile(path.join(runnerDir, 'adapters/shared/json-field.sh'), path.join(harnessDir, 'scripts/lib/json-field.sh'));
|
|
113
|
+
copyFile(path.join(runnerDir, 'adapters/shared/log-tui.mjs'), path.join(harnessDir, 'scripts/lib/log-tui.mjs'));
|
|
118
114
|
makeExecutableTree(path.join(harnessDir, 'scripts'));
|
|
119
115
|
fs.writeFileSync(path.join(harnessDir, 'installed-scripts.sha256'), `${dirContentHash(path.join(harnessDir, 'scripts'))}\n`);
|
|
120
116
|
|
|
121
|
-
const cleanupScript = path.join(runnerDir, '
|
|
117
|
+
const cleanupScript = path.join(runnerDir, 'adapters/extension/cleanup.mjs');
|
|
122
118
|
const cleanupCommand = `RECIPE_HARNESS_ROOT=${harnessRoot} ${shellQuote(cleanupScript)} --target ${shellQuote(target)}`;
|
|
123
119
|
const manifest = {
|
|
124
120
|
adapter: 'extension',
|
|
@@ -132,7 +128,7 @@ const manifest = {
|
|
|
132
128
|
target,
|
|
133
129
|
protocolVersion: 'v1',
|
|
134
130
|
actionManifestPath: `${harnessRel}/action-manifest.json`,
|
|
135
|
-
runnerEntrypoint: `${harnessRel}/runner/bin/
|
|
131
|
+
runnerEntrypoint: `${harnessRel}/runner/bin/mm-harness`,
|
|
136
132
|
installedPaths: [`${harnessRel}/scripts`, `${harnessRel}/runner`, `${harnessRel}/action-manifest.json`, `${harnessRel}/manifest.json`],
|
|
137
133
|
runtimeHelpers: {
|
|
138
134
|
live: `${harnessRel}/scripts/live.sh`,
|
|
@@ -149,7 +145,7 @@ fs.writeFileSync(path.join(harnessDir, 'manifest.json'), `${JSON.stringify(manif
|
|
|
149
145
|
|
|
150
146
|
if (gitExclude) addGitExclude(target, `${harnessRoot}/`, harnessDir);
|
|
151
147
|
|
|
152
|
-
const ensureDeps = path.join(runnerDir, '
|
|
148
|
+
const ensureDeps = path.join(runnerDir, 'adapters/shared/ensure-runner-deps.sh');
|
|
153
149
|
if (fs.existsSync(ensureDeps)) {
|
|
154
150
|
const ensured = spawnSync('bash', [ensureDeps, runnerDir], { stdio: 'inherit' });
|
|
155
151
|
if (ensured.status !== 0) process.exit(ensured.status ?? 1);
|
|
@@ -45,12 +45,12 @@ fi
|
|
|
45
45
|
|
|
46
46
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
47
47
|
# shellcheck disable=SC1091
|
|
48
|
-
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../
|
|
48
|
+
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../shared/harness-path.sh"; do
|
|
49
49
|
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
50
50
|
done
|
|
51
51
|
unset _hp
|
|
52
52
|
if ! command -v harness_root >/dev/null 2>&1; then
|
|
53
|
-
echo "mm-harness: shared lib
|
|
53
|
+
echo "mm-harness: shared lib adapters/shared/harness-path.sh not found; reinstall the runner." >&2
|
|
54
54
|
exit 1
|
|
55
55
|
fi
|
|
56
56
|
READINESS_MJS="$SCRIPT_DIR/readiness.mjs"
|
|
@@ -64,12 +64,12 @@ ARTIFACTS="${ARTIFACTS:-$HARNESS_DIR/launch/$(date -u +%Y%m%dT%H%M%SZ)}"
|
|
|
64
64
|
mkdir -p "$ARTIFACTS/logs"
|
|
65
65
|
|
|
66
66
|
if [ ! -f "$HARNESS_DIR/manifest.json" ]; then
|
|
67
|
-
echo "Extension recipe harness is not installed in $TARGET. Run
|
|
67
|
+
echo "Extension recipe harness is not installed in $TARGET. Run mm-harness install --adapter extension --target $TARGET first." >&2
|
|
68
68
|
exit 1
|
|
69
69
|
fi
|
|
70
70
|
|
|
71
71
|
LIB_DIR=""
|
|
72
|
-
for _lib in "$SCRIPT_DIR/lib" "$SCRIPT_DIR/../
|
|
72
|
+
for _lib in "$SCRIPT_DIR/lib" "$SCRIPT_DIR/../shared"; do
|
|
73
73
|
[ -f "$_lib/log-tui.mjs" ] && LIB_DIR="$_lib" && break
|
|
74
74
|
done
|
|
75
75
|
unset _lib
|
|
@@ -68,18 +68,18 @@ esac
|
|
|
68
68
|
|
|
69
69
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
70
70
|
# shellcheck disable=SC1091
|
|
71
|
-
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../
|
|
71
|
+
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../shared/harness-path.sh"; do
|
|
72
72
|
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
73
73
|
done
|
|
74
74
|
unset _hp
|
|
75
75
|
if ! command -v harness_root >/dev/null 2>&1; then
|
|
76
|
-
echo "mm-harness: shared lib
|
|
76
|
+
echo "mm-harness: shared lib adapters/shared/harness-path.sh not found; reinstall the runner." >&2
|
|
77
77
|
exit 1
|
|
78
78
|
fi
|
|
79
79
|
# verify.sh is a recipe-tree feature: co-located in installed copies, under
|
|
80
|
-
#
|
|
80
|
+
# adapters/extension in a repo checkout.
|
|
81
81
|
VERIFY_SH=""
|
|
82
|
-
for _v in "$SCRIPT_DIR/verify.sh" "$SCRIPT_DIR/../../
|
|
82
|
+
for _v in "$SCRIPT_DIR/verify.sh" "$SCRIPT_DIR/../../adapters/extension/verify.sh"; do
|
|
83
83
|
[ -f "$_v" ] && { VERIFY_SH="$_v"; break; }
|
|
84
84
|
done
|
|
85
85
|
unset _v
|
|
@@ -92,7 +92,7 @@ RUNTIME_DIR="$(recipe_runtime_dir)"
|
|
|
92
92
|
# Runner bin (installed wrapper → source runner). Used by the watch prepare path
|
|
93
93
|
# to defer the cache-clear DECISION to `runtime-decision` (single source) and to
|
|
94
94
|
# record the deps/cache baseline after a confirmed-good build.
|
|
95
|
-
RUNNER_BIN="$(harness_dir "$TARGET" extension)/runner/bin/
|
|
95
|
+
RUNNER_BIN="$(harness_dir "$TARGET" extension)/runner/bin/mm-harness"
|
|
96
96
|
OUT="${OUT:-$(harness_root)/extension/runner/recipes}"
|
|
97
97
|
ARTIFACTS="${ARTIFACTS:-$(harness_dir "$TARGET" extension)/live/$(date -u +%Y%m%dT%H%M%SZ)}"
|
|
98
98
|
mkdir -p "$ARTIFACTS/logs"
|
|
@@ -26,8 +26,8 @@ const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
|
26
26
|
function pathDefault(key) {
|
|
27
27
|
for (const candidate of [
|
|
28
28
|
path.join(scriptDir, 'lib/path-defaults.json'),
|
|
29
|
-
path.join(scriptDir, '../
|
|
30
|
-
path.join(scriptDir, '../../
|
|
29
|
+
path.join(scriptDir, '../shared/path-defaults.json'),
|
|
30
|
+
path.join(scriptDir, '../../adapters/shared/path-defaults.json'),
|
|
31
31
|
]) {
|
|
32
32
|
if (!fs.existsSync(candidate)) continue;
|
|
33
33
|
const value = JSON.parse(fs.readFileSync(candidate, 'utf8'))[key];
|
|
@@ -110,7 +110,16 @@ function writeExtensionId(target, extensionId) {
|
|
|
110
110
|
return true;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
// All callers target the local Chrome CDP endpoint (127.0.0.1:<cdpPort>).
|
|
114
|
+
// Validate before requesting so file-derived data cannot redirect to a remote host.
|
|
115
|
+
function assertLocalUrl(url) {
|
|
116
|
+
if (!/^http:\/\/127\.0\.0\.1:\d+\//u.test(url)) {
|
|
117
|
+
throw new Error(`readiness: refusing non-local URL: ${url}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
113
121
|
function httpJson(url, timeoutMs = 3000) {
|
|
122
|
+
assertLocalUrl(url);
|
|
114
123
|
return new Promise((resolve, reject) => {
|
|
115
124
|
const req = http.get(url, (res) => {
|
|
116
125
|
let data = '';
|
|
@@ -134,6 +143,7 @@ function httpJson(url, timeoutMs = 3000) {
|
|
|
134
143
|
}
|
|
135
144
|
|
|
136
145
|
function httpJsonRequest(method, url, timeoutMs = 3000) {
|
|
146
|
+
assertLocalUrl(url);
|
|
137
147
|
return new Promise((resolve, reject) => {
|
|
138
148
|
const req = http.request(url, { method }, (res) => {
|
|
139
149
|
let data = '';
|
|
@@ -85,7 +85,7 @@ fi
|
|
|
85
85
|
|
|
86
86
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
87
87
|
# shellcheck disable=SC1091
|
|
88
|
-
for _arn in "$SCRIPT_DIR/lib/activate-repo-node.sh" "$SCRIPT_DIR/../
|
|
88
|
+
for _arn in "$SCRIPT_DIR/lib/activate-repo-node.sh" "$SCRIPT_DIR/../shared/activate-repo-node.sh"; do
|
|
89
89
|
[ -f "$_arn" ] && { . "$_arn"; break; }
|
|
90
90
|
done
|
|
91
91
|
unset _arn
|
|
@@ -115,7 +115,7 @@ resolve_fixture_script() {
|
|
|
115
115
|
if [ "$SUBCOMMAND" = resolve ]; then
|
|
116
116
|
RUNTIME_DIR=""
|
|
117
117
|
# shellcheck disable=SC1091
|
|
118
|
-
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../
|
|
118
|
+
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../shared/harness-path.sh"; do
|
|
119
119
|
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
120
120
|
done
|
|
121
121
|
unset _hp
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
#
|
|
10
10
|
# Inputs (flags / env):
|
|
11
11
|
# --target <metamask-extension> (default $PWD; becomes the working dir)
|
|
12
|
-
# --runtime-dir <rel> (default from
|
|
12
|
+
# --runtime-dir <rel> (default from adapters/shared path-defaults)
|
|
13
13
|
# --watcher-port <port> (default env WATCHER_PORT/RECIPE_WATCHER_PORT,
|
|
14
14
|
# runtime json, or slot suffix e.g. metamask-extension-1 => 9011)
|
|
15
15
|
# --runner-bin <path> (optional; records deps/cache baseline best-effort)
|
|
@@ -48,18 +48,18 @@ done
|
|
|
48
48
|
|
|
49
49
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
50
50
|
# shellcheck disable=SC1091
|
|
51
|
-
for _arn in "$SCRIPT_DIR/lib/activate-repo-node.sh" "$SCRIPT_DIR/../
|
|
51
|
+
for _arn in "$SCRIPT_DIR/lib/activate-repo-node.sh" "$SCRIPT_DIR/../shared/activate-repo-node.sh"; do
|
|
52
52
|
[ -f "$_arn" ] && { . "$_arn"; break; }
|
|
53
53
|
done
|
|
54
54
|
unset _arn
|
|
55
55
|
if [ -z "$RUNTIME_DIR" ]; then
|
|
56
56
|
# shellcheck disable=SC1091
|
|
57
|
-
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../
|
|
57
|
+
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../shared/harness-path.sh"; do
|
|
58
58
|
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
59
59
|
done
|
|
60
60
|
unset _hp
|
|
61
61
|
if ! command -v recipe_runtime_dir >/dev/null 2>&1; then
|
|
62
|
-
echo "start-watch: shared lib
|
|
62
|
+
echo "start-watch: shared lib adapters/shared/harness-path.sh not found; pass --runtime-dir." >&2
|
|
63
63
|
exit 1
|
|
64
64
|
fi
|
|
65
65
|
RUNTIME_DIR="$(recipe_runtime_dir)"
|
|
@@ -67,7 +67,7 @@ fi
|
|
|
67
67
|
|
|
68
68
|
cd "$TARGET"
|
|
69
69
|
REPO_NODE_PATH_PREFIX=""
|
|
70
|
-
for _arn in "$SCRIPT_DIR/lib/activate-repo-node.sh" "$SCRIPT_DIR/../
|
|
70
|
+
for _arn in "$SCRIPT_DIR/lib/activate-repo-node.sh" "$SCRIPT_DIR/../shared/activate-repo-node.sh"; do
|
|
71
71
|
[ -f "$_arn" ] && { # shellcheck disable=SC1090
|
|
72
72
|
. "$_arn"
|
|
73
73
|
break
|
|
@@ -182,7 +182,7 @@ slot_number() {
|
|
|
182
182
|
|
|
183
183
|
# Explicit clean-build path: clear the target-scoped webpack cache before
|
|
184
184
|
# starting the harness-owned watcher. Faster incremental refresh stays on
|
|
185
|
-
# `
|
|
185
|
+
# `mm-harness refresh`; this script is for proving a clean build works.
|
|
186
186
|
echo '[recipe-harness] clean build: clearing webpack cache + harness watcher'
|
|
187
187
|
rm -rf node_modules/.cache/webpack
|
|
188
188
|
killed_harness_pid=""
|
|
@@ -228,7 +228,7 @@ watch_log="$RUNTIME_DIR/recipe-harness-webpack.log"
|
|
|
228
228
|
rm -f "$watch_pid_file"
|
|
229
229
|
: > "$watch_log"
|
|
230
230
|
LIB_DIR=""
|
|
231
|
-
for _lib in "$SCRIPT_DIR/lib" "$SCRIPT_DIR/../
|
|
231
|
+
for _lib in "$SCRIPT_DIR/lib" "$SCRIPT_DIR/../shared"; do
|
|
232
232
|
[ -f "$_lib/log-tui.mjs" ] && LIB_DIR="$_lib" && break
|
|
233
233
|
done
|
|
234
234
|
unset _lib
|
|
@@ -49,12 +49,12 @@ fi
|
|
|
49
49
|
|
|
50
50
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
51
51
|
# shellcheck disable=SC1091
|
|
52
|
-
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../../
|
|
52
|
+
for _hp in "$SCRIPT_DIR/lib/harness-path.sh" "$SCRIPT_DIR/../../adapters/shared/harness-path.sh" "$SCRIPT_DIR/../shared/harness-path.sh"; do
|
|
53
53
|
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
54
54
|
done
|
|
55
55
|
unset _hp
|
|
56
56
|
if ! command -v harness_root >/dev/null 2>&1; then
|
|
57
|
-
echo "extension verify: shared lib
|
|
57
|
+
echo "extension verify: shared lib adapters/shared/harness-path.sh not found; reinstall the harness." >&2
|
|
58
58
|
exit 1
|
|
59
59
|
fi
|
|
60
60
|
|
|
@@ -84,7 +84,7 @@ RUNTIME_DIR="$(recipe_runtime_dir)"
|
|
|
84
84
|
HARNESS_ROOT="$(harness_root)"
|
|
85
85
|
HARNESS_REL="$HARNESS_ROOT/extension"
|
|
86
86
|
HARNESS_DIR="$(harness_dir "$TARGET" extension)"
|
|
87
|
-
RUNNER_BIN="$HARNESS_DIR/runner/bin/
|
|
87
|
+
RUNNER_BIN="$HARNESS_DIR/runner/bin/mm-harness"
|
|
88
88
|
# --out (optional): a task-local recipes dir. Resolve it safely within the target
|
|
89
89
|
# (resolve_harness_out rejects absolute/.. escapes) and prefer its smoke recipe so
|
|
90
90
|
# `live --out <dir>` does not silently fall back to the installed default.
|
|
@@ -108,22 +108,22 @@ ARTIFACTS="${ARTIFACTS:-$HARNESS_DIR/verify/$(date -u +%Y%m%dT%H%M%SZ)}"
|
|
|
108
108
|
mkdir -p "$ARTIFACTS/logs"
|
|
109
109
|
EXTENSION_ID_FILE="$TARGET/$RUNTIME_DIR/extension.id"
|
|
110
110
|
# Shared JSON reader: $SCRIPT_DIR/lib when running from the installed copy,
|
|
111
|
-
# else the runner canonical at
|
|
111
|
+
# else the runner canonical at adapters/shared.
|
|
112
112
|
# shellcheck disable=SC1091
|
|
113
|
-
for _lib in "$SCRIPT_DIR/lib/json-field.sh" "$SCRIPT_DIR/../../
|
|
113
|
+
for _lib in "$SCRIPT_DIR/lib/json-field.sh" "$SCRIPT_DIR/../../adapters/shared/json-field.sh"; do
|
|
114
114
|
[ -f "$_lib" ] && { . "$_lib"; break; }
|
|
115
115
|
done
|
|
116
116
|
unset _lib
|
|
117
117
|
# Fail fast with an actionable message if neither path loaded (e.g. an install that
|
|
118
118
|
# predates the lib co-location), instead of a cryptic later `set -e` abort.
|
|
119
119
|
if ! command -v read_runtime_context_field >/dev/null 2>&1; then
|
|
120
|
-
echo "extension verify: json-field helper missing (
|
|
120
|
+
echo "extension verify: json-field helper missing (adapters/shared/json-field.sh). Run mm-harness extension prepare --target $TARGET" >&2
|
|
121
121
|
exit 1
|
|
122
122
|
fi
|
|
123
123
|
# readiness probe is app control: co-located in installed copies, under
|
|
124
|
-
#
|
|
124
|
+
# adapters/extension in a repo checkout.
|
|
125
125
|
READINESS_MJS=""
|
|
126
|
-
for _r in "$SCRIPT_DIR/readiness.mjs" "$SCRIPT_DIR/../../
|
|
126
|
+
for _r in "$SCRIPT_DIR/readiness.mjs" "$SCRIPT_DIR/../../adapters/extension/readiness.mjs"; do
|
|
127
127
|
[ -f "$_r" ] && { READINESS_MJS="$_r"; break; }
|
|
128
128
|
done
|
|
129
129
|
unset _r
|
|
@@ -290,7 +290,7 @@ check_file() {
|
|
|
290
290
|
|
|
291
291
|
check_file "$HARNESS_REL/manifest.json"
|
|
292
292
|
check_file "$HARNESS_REL/action-manifest.json"
|
|
293
|
-
check_file "$HARNESS_REL/runner/bin/
|
|
293
|
+
check_file "$HARNESS_REL/runner/bin/mm-harness"
|
|
294
294
|
check_file "$HARNESS_REL/runner/manifests/extension.action-manifest.json"
|
|
295
295
|
|
|
296
296
|
# dist-freshness + build-health now come from the runner's single source of
|
|
@@ -327,7 +327,7 @@ const blMsg = bl.status === "ok" ? "webpack compiled."
|
|
|
327
327
|
: bl.status === "no-watch" ? "no webpack watch log; build-health n/a (e.g. one-shot build)."
|
|
328
328
|
: bl.status === "building" ? "webpack has not reported a successful compile yet."
|
|
329
329
|
: bl.status === "errors" ? (bl.reason === "stale-cache"
|
|
330
|
-
? "webpack build failing on a stale cache (ENOENT on a deduped module). Run `
|
|
330
|
+
? "webpack build failing on a stale cache (ENOENT on a deduped module). Run `mm-harness runtime-launch --adapter extension --target <repo> --cdp-port <port>` to auto-clear the cache and rebuild."
|
|
331
331
|
: "webpack build has errors; fix the source/build before validating.")
|
|
332
332
|
: "build-health unknown.";
|
|
333
333
|
fs.writeFileSync(dir + "/build-health.json", JSON.stringify({ status: bl.status, reason: bl.reason, excerpt: bl.excerpt, message: blMsg }));
|
|
@@ -399,7 +399,7 @@ if [ "$STATIC_ONLY" = false ]; then
|
|
|
399
399
|
|
|
400
400
|
if (
|
|
401
401
|
cd "$TARGET"
|
|
402
|
-
"$RUNNER_BIN"
|
|
402
|
+
"$RUNNER_BIN" actions --raw --adapter extension
|
|
403
403
|
) > "$ARTIFACTS/logs/runner-manifest.json" 2> "$ARTIFACTS/logs/runner-manifest.err"; then
|
|
404
404
|
checks+=("{\"name\":\"runner manifest\",\"status\":\"pass\"}")
|
|
405
405
|
else
|
|
@@ -41,8 +41,8 @@ function usage() {
|
|
|
41
41
|
function pathDefault(key) {
|
|
42
42
|
for (const candidate of [
|
|
43
43
|
path.join(__dirname, 'lib/path-defaults.json'),
|
|
44
|
-
path.join(__dirname, '../
|
|
45
|
-
path.join(__dirname, '../../
|
|
44
|
+
path.join(__dirname, '../shared/path-defaults.json'),
|
|
45
|
+
path.join(__dirname, '../../adapters/shared/path-defaults.json'),
|
|
46
46
|
]) {
|
|
47
47
|
if (!fs.existsSync(candidate)) continue;
|
|
48
48
|
const value = JSON.parse(fs.readFileSync(candidate, 'utf8'))[key];
|