@deeeed/metamask-harness 0.17.4 → 0.18.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 +775 -0
- package/README.md +65 -71
- package/adapters/extension/ensure-browser.sh +12 -1
- package/adapters/extension/inject.mjs +7 -0
- package/adapters/extension/launch-browser.cjs +10 -3
- package/adapters/extension/lib/chrome-args.cjs +31 -0
- package/adapters/extension/lib/macos-focus.cjs +32 -0
- package/adapters/extension/live.sh +10 -20
- package/adapters/manifest.json +8 -0
- package/adapters/mobile/open-device.sh +45 -7
- package/adapters/mobile/verify.sh +15 -3
- package/adapters/shared/harness-source-fingerprint.mjs +49 -0
- package/adapters/shared/install-repo-deps.sh +1 -5
- package/adapters/shared/open-debug.mjs +184 -103
- package/adapters/shared/resolve-slot-ports-core.mjs +23 -6
- package/adapters/shared/resolve-slot-ports.sh +22 -5
- package/bin/mm-harness +15 -3
- package/dist/adapters/core/surface.js +4 -1
- package/dist/adapters/extension/console-capture.js +3 -1
- package/dist/adapters/extension/harness-freshness.js +39 -0
- package/dist/adapters/extension/product-config.js +110 -0
- package/dist/adapters/extension/runtime-decision.js +20 -71
- package/dist/adapters/extension/surface.js +19 -1
- package/dist/adapters/mobile/prepare.js +17 -0
- package/dist/adapters/mobile/source-freshness.js +26 -41
- package/dist/adapters/mobile/surface.js +4 -1
- package/dist/adapters/resolve-slot-ports.js +2 -0
- package/dist/adapters/slot-ports.js +13 -32
- package/dist/adapters.js +50 -17
- package/dist/checkout-lock.js +27 -2
- package/dist/cli-color.js +19 -0
- package/dist/cli-commands.js +1 -1
- package/dist/cli.js +2 -3
- package/dist/command-contract.js +13 -3
- package/dist/commands/call.js +115 -29
- package/dist/commands/checklist.js +4 -1
- package/dist/commands/completion-candidates.js +20 -13
- package/dist/commands/debug.js +31 -38
- package/dist/commands/doctor.js +33 -6
- package/dist/commands/fixtures.js +65 -17
- package/dist/commands/flows.js +39 -10
- package/dist/commands/launch/extension.js +40 -15
- package/dist/commands/launch/index.js +41 -5
- package/dist/commands/list-executables.js +151 -29
- package/dist/commands/manifest.js +127 -18
- package/dist/commands/parse-args.js +11 -1
- package/dist/commands/run-engine.js +384 -56
- package/dist/commands/run.js +112 -17
- package/dist/commands/shared.js +22 -2
- package/dist/commands/status-probe.js +3 -0
- package/dist/commands/status.js +1 -0
- package/dist/completions-cache.js +1 -1
- package/dist/doctor.js +56 -6
- package/dist/harness.js +6 -5
- package/dist/heal-bounds.js +1 -1
- package/dist/live-adapter-contract.js +132 -12
- package/dist/manifest.js +161 -1
- package/dist/mm-harness-cli.js +13 -7
- package/dist/recipe-security.js +178 -0
- package/dist/runner.js +87 -13
- package/dist/runtime-context.js +8 -26
- package/docs/CONTRIBUTING.md +137 -0
- package/docs/QA.md +185 -0
- package/docs/RECIPES.md +161 -0
- package/docs/SECURITY.md +88 -0
- package/library/actions/core/perps/read_account.mjs +2 -2
- package/library/actions/core/perps/read_orders.mjs +2 -1
- package/library/actions/core/perps/read_positions.mjs +2 -1
- package/library/actions/core/wallet/list_accounts.mjs +95 -0
- package/library/actions/extension/platform/cdp.mjs +1 -0
- package/library/actions/extension/wallet/list_accounts.mjs +41 -0
- package/library/actions/mobile/platform/bridge.mjs +1 -5
- package/library/actions/mobile/wallet/list_accounts.mjs +37 -0
- package/library/manifests/core.action-manifest.json +61 -0
- package/library/manifests/extension.action-manifest.json +53 -0
- package/library/manifests/mobile.action-manifest.json +53 -0
- package/library/recipes/runner/action-validation.extension.recipe.json +8 -1
- package/library/recipes/runner/action-validation.mobile.recipe.json +8 -1
- package/package.json +10 -6
- package/scripts/completions.sh +7 -7
- package/docs/ADAPTER-SURFACE.md +0 -26
- package/docs/CHEATSHEET.md +0 -48
- package/docs/CLI-ERGONOMICS-AUDIT.md +0 -32
- package/docs/CLI-ERGONOMICS-HUMAN-QA.md +0 -64
- package/docs/CODE-MAP.md +0 -62
- package/docs/UX-PRINCIPLES.md +0 -66
- package/docs/VIDEO-DEMO-VALIDATION.md +0 -74
- package/docs/architecture.md +0 -88
- package/docs/live-adapter-contract.md +0 -190
- package/docs/package-boundaries.md +0 -47
- package/docs/perps-flow-catalog.md +0 -235
- package/docs/recipe-libraries.md +0 -71
- package/docs/runtime-file-conventions.md +0 -36
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
<!-- Generated by scripts/generate-cli-ergonomics-audit.mjs. Do not edit by hand. -->
|
|
2
|
-
# CLI ergonomics audit
|
|
3
|
-
|
|
4
|
-
This matrix tracks the public command surface. “Covered” means the shared preflight contract and
|
|
5
|
-
`tests/contract/cli-teaching-errors.test.sh` exercise the behavior without dispatching runtime work.
|
|
6
|
-
Runtime recovery is claimed only where command-specific failures return a stable `userAction`.
|
|
7
|
-
Success hints are intentionally limited to lifecycle transitions with one truthful next command;
|
|
8
|
-
discovery, read-only, and terminal evidence commands do not invent one. ID prefix support is N/A
|
|
9
|
-
unless a command displays a shortened ID that another command accepts.
|
|
10
|
-
|
|
11
|
-
| Command | Bad flag | First feedback | `--json` recovery | Success next step | Displayed ID prefix |
|
|
12
|
-
|---|---|---|---|---|---|
|
|
13
|
-
| `status` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | structured `next` | N/A: command displays no shortened ID |
|
|
14
|
-
| `checklist` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage errors covered; no runtime recovery claim | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
15
|
-
| `actions` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
16
|
-
| `stop` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | launch `next` when the adapter has one unambiguous launch | N/A: command displays no shortened ID |
|
|
17
|
-
| `call` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
18
|
-
| `flows` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage errors covered; no runtime recovery claim | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
19
|
-
| `run` | covered: `CLI_UNKNOWN_OPTION` | TTY intent before slow work; machine output clean | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
20
|
-
| `last` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
21
|
-
| `doctor` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
22
|
-
| `check` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
23
|
-
| `recipe-quality` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
24
|
-
| `provision` | covered: `CLI_UNKNOWN_OPTION` | TTY intent before slow work; machine output clean | usage + runtime `error.code/message/userAction` | launch `next` after install | N/A: command displays no shortened ID |
|
|
25
|
-
| `install` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | verify `next` | N/A: command displays no shortened ID |
|
|
26
|
-
| `verify` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | status `next` | N/A: command displays no shortened ID |
|
|
27
|
-
| `cleanup` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | install `next` | N/A: command displays no shortened ID |
|
|
28
|
-
| `launch` | covered: `CLI_UNKNOWN_OPTION` | TTY intent before slow work; machine output clean | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
29
|
-
| `logs` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
30
|
-
| `debug` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage errors covered; no runtime recovery claim | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
31
|
-
| `update` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
32
|
-
| `fixtures` | covered: `CLI_UNKNOWN_OPTION` | N/A: no newly introduced slow path | usage + runtime `error.code/message/userAction` | N/A: discovery, read-only, or terminal result | N/A: command displays no shortened ID |
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# Human QA
|
|
2
|
-
|
|
3
|
-
Run this from each product checkout before a release. Verify the visible outcome,
|
|
4
|
-
not only the exit code.
|
|
5
|
-
|
|
6
|
-
Run the non-visual gate first:
|
|
7
|
-
|
|
8
|
-
```bash
|
|
9
|
-
yarn qa:human \
|
|
10
|
-
--extension /path/to/metamask-extension \
|
|
11
|
-
--mobile /path/to/metamask-mobile \
|
|
12
|
-
--core /path/to/metamask-core \
|
|
13
|
-
--artifacts-dir temp/human-qa
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
It verifies live readiness, installed runtime, debugger target resolution, smoke
|
|
17
|
-
evidence, and unchanged tracked product source. The checks below cover outcomes
|
|
18
|
-
that still require eyes or an intentional source edit.
|
|
19
|
-
|
|
20
|
-
## Common
|
|
21
|
-
|
|
22
|
-
- [ ] `mm-harness --version` prints the candidate version.
|
|
23
|
-
- [ ] `mm-harness doctor` detects the correct product and reports only current
|
|
24
|
-
configuration.
|
|
25
|
-
- [ ] Without `capture-helper`, `doctor` names the CDP or simulator/ADB screenshot
|
|
26
|
-
fallback and says video is unavailable.
|
|
27
|
-
- [ ] A misspelled flag explains the error and gives a runnable next command.
|
|
28
|
-
- [ ] `mm-harness actions` and `mm-harness flows` return useful, bounded discovery.
|
|
29
|
-
- [ ] `mm-harness fixtures set` either applies the fixture or names the missing
|
|
30
|
-
file and exact recovery action.
|
|
31
|
-
- [ ] `mm-harness run <safe-recipe> --artifacts-dir temp/qa-proof` prints findings,
|
|
32
|
-
diagnostics, and absolute evidence paths.
|
|
33
|
-
- [ ] `mm-harness last --json` identifies that run without rerunning it.
|
|
34
|
-
- [ ] `mm-harness doctor --json` is one parseable document with no human decoration.
|
|
35
|
-
|
|
36
|
-
## Extension
|
|
37
|
-
|
|
38
|
-
- [ ] `mm-harness launch` opens/reuses the checkout's named Chrome profile.
|
|
39
|
-
- [ ] `mm-harness launch --sidepanel` opens the MetaMask sidepanel without extra
|
|
40
|
-
Extension tabs.
|
|
41
|
-
- [ ] `mm-harness debug` opens connected DevTools for the active MetaMask target.
|
|
42
|
-
- [ ] `mm-harness logs --source extension` shows Extension console events.
|
|
43
|
-
- [ ] `mm-harness logs --source dapp` shows dapp console events separately.
|
|
44
|
-
- [ ] Edit a visible source string twice, waiting for successful incremental
|
|
45
|
-
compilation after each edit; refresh the browser and confirm both changes.
|
|
46
|
-
- [ ] Revert the edit, confirm a third incremental compilation, and verify the
|
|
47
|
-
same watcher and Chrome process were reused.
|
|
48
|
-
|
|
49
|
-
## Mobile
|
|
50
|
-
|
|
51
|
-
- [ ] `mm-harness launch ios` boots/reuses the intended simulator and opens the app.
|
|
52
|
-
- [ ] `mm-harness launch android` targets the intended emulator/device.
|
|
53
|
-
- [ ] `mm-harness logs --source metro` and `--source app` show distinct streams.
|
|
54
|
-
- [ ] `mm-harness debug` opens the usable React Native developer surface.
|
|
55
|
-
- [ ] Change a visible JS string, confirm Metro rebuilds, reload the app, and see
|
|
56
|
-
the change without a native rebuild.
|
|
57
|
-
|
|
58
|
-
## Core
|
|
59
|
-
|
|
60
|
-
- [ ] `mm-harness status`, `doctor`, `actions`, `flows`, and a safe recipe run work
|
|
61
|
-
without browser/device assumptions.
|
|
62
|
-
|
|
63
|
-
Record the command, version, checkout SHA, visible mismatch, exit code, and JSON
|
|
64
|
-
error envelope for any failure.
|
package/docs/CODE-MAP.md
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# Code map — where things live and how a command flows
|
|
2
|
-
|
|
3
|
-
One page for humans. The contracts live in docs/UX-PRINCIPLES.md and
|
|
4
|
-
docs/ADAPTER-SURFACE.md; this is the geography.
|
|
5
|
-
|
|
6
|
-
## How a command flows
|
|
7
|
-
|
|
8
|
-
```
|
|
9
|
-
bin/mm-harness bash front door: MM_HARNESS_BIN dev/prod switch,
|
|
10
|
-
│ dist-vs-src selection (dist wins when present;
|
|
11
|
-
│ stale-dist warning), deps ensure
|
|
12
|
-
▼
|
|
13
|
-
src/mm-harness-cli.ts commander surface: grouped colored help, per-command
|
|
14
|
-
│ --help and usage errors; delegates in-process
|
|
15
|
-
▼
|
|
16
|
-
src/cli.ts parse + dispatch ONLY — no verb logic lives here
|
|
17
|
-
│
|
|
18
|
-
├── src/commands/<verb>.ts one module per verb (doctor, stop, call, run,
|
|
19
|
-
│ │ provision, fixtures, flows, logs, debug, …)
|
|
20
|
-
│ ▼
|
|
21
|
-
│ src/adapters/surface.ts AdapterSurface registry — per-platform behavior
|
|
22
|
-
│ │ (ports, runtime status, dev server, log sources)
|
|
23
|
-
│ ▼
|
|
24
|
-
│ src/adapters/{mobile,extension,core}/ TS logic per platform
|
|
25
|
-
│
|
|
26
|
-
└── src/harness.ts overlay lifecycle (install/verify/cleanup) — writes
|
|
27
|
-
│ the per-checkout overlay + runner delegate
|
|
28
|
-
▼
|
|
29
|
-
adapters/ SHELL LEAVES (repo root — not src/adapters!):
|
|
30
|
-
mobile/ extension/ single-OS-op scripts the TS layer spawns
|
|
31
|
-
core/ shared/ (simctl/adb/tmux/metro/webpack lifecycle)
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## The two `adapters/` directories
|
|
35
|
-
|
|
36
|
-
- `adapters/` (repo root) — executable shell leaves. Thin, OS-facing, spawned by TS.
|
|
37
|
-
- `src/adapters/` — TypeScript platform logic behind the AdapterSurface.
|
|
38
|
-
Rule: logic/decisions in TS; a leaf only executes. A leaf converts to TS only when
|
|
39
|
-
it starts making decisions (see backlog ruling), never as a campaign.
|
|
40
|
-
|
|
41
|
-
## Other roots
|
|
42
|
-
|
|
43
|
-
- `library/` — recipe library: actions (`library/actions/<adapter>/…`, executable
|
|
44
|
-
action modules — importing one RUNS it, see library/README.md), flows, recipes.
|
|
45
|
-
- `tests/contract/` — hermetic bash contract tests (PATH-stubbed OS tools). The
|
|
46
|
-
launch-leaf-flags test enforces composer↔leaf flag agreement.
|
|
47
|
-
- `dist/` — esbuild output; the ONLY thing published runs. gitignored; in a source
|
|
48
|
-
checkout it SHADOWS src when present (bin warns when it goes stale).
|
|
49
|
-
- Per-checkout runtime state lives in the TARGET repo: `temp/recipe/runtime/`
|
|
50
|
-
(context, logs, wallet fixture) and `temp/recipe/harness/<adapter>/` (overlay +
|
|
51
|
-
runner delegate pinned to the installing bin via `.runner-source`).
|
|
52
|
-
|
|
53
|
-
## Adding things
|
|
54
|
-
|
|
55
|
-
- **A verb**: module in `src/commands/`, register in `src/cli.ts` dispatch + the
|
|
56
|
-
commander metadata in `src/mm-harness-cli.ts` (help group), contract test.
|
|
57
|
-
- **A flag**: parse in the verb module; if it reaches a leaf, the leaf's parser
|
|
58
|
-
must accept it (launch-leaf-flags test will fail otherwise) — or pass via env.
|
|
59
|
-
- **A leaf**: shell under `adapters/<platform>/`, spawned via the shared spawn
|
|
60
|
-
helpers (never raw exec), contract test with PATH stubs, errors teach escape.
|
|
61
|
-
- **A platform behavior**: extend the AdapterSurface, implement per platform —
|
|
62
|
-
verbs must not branch on adapter for surface-owned behavior.
|
package/docs/UX-PRINCIPLES.md
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# UX principles — the mm-harness interaction contract
|
|
2
|
-
|
|
3
|
-
Every command surface follows these rules. They are review criteria, not aspirations:
|
|
4
|
-
a PR that adds a command or output path is checked against each one.
|
|
5
|
-
|
|
6
|
-
**Scope: the HUMAN surface.** The agent contract is exempt and inviolable: under
|
|
7
|
-
`--json`, stdout carries exactly one machine-readable envelope — no color, no
|
|
8
|
-
banners, no decorative lines. Progress/streaming exists
|
|
9
|
-
for agents too, but only ever on stderr. When a rule below conflicts with envelope
|
|
10
|
-
purity, the envelope wins.
|
|
11
|
-
|
|
12
|
-
## 1. Context-aware by default
|
|
13
|
-
The CLI answers relative to the checkout it is standing in.
|
|
14
|
-
- Adapter is auto-detected everywhere (`--adapter` overrides; a bare command never
|
|
15
|
-
fails on a value detection can supply).
|
|
16
|
-
- The slot context the orchestrator wrote into the checkout
|
|
17
|
-
(`<runtime_dir>/agentic-runtime.json`) is the authoritative source for device,
|
|
18
|
-
ports, and slot identity — naming formulas are last-resort fallbacks and never
|
|
19
|
-
hardcode pool prefixes (they go stale on rename).
|
|
20
|
-
- Output is scoped to the platform: an extension-only field is noise on a mobile
|
|
21
|
-
slot; help, flag lists, and completion candidates shrink to what applies here.
|
|
22
|
-
- Enforcement: platform-specific behavior is resolved through the adapter surface
|
|
23
|
-
(`getAdapterSurface(adapter)`), never a per-command `if (adapter === …)` ladder —
|
|
24
|
-
that ladder is how commands go platform-blind. See docs/ADAPTER-SURFACE.md.
|
|
25
|
-
|
|
26
|
-
## 2. Never silent, never opaque
|
|
27
|
-
Long operations show intent immediately and progress continuously.
|
|
28
|
-
- First line within milliseconds: what is being done, where (device/port), and
|
|
29
|
-
where the full log lives.
|
|
30
|
-
- Add an explicit first line only when work can block before existing output. Fast
|
|
31
|
-
commands use their result as acknowledgement; they do not print a redundant banner.
|
|
32
|
-
- Leaf output streams live to stderr — `--json` reserves stdout for the envelope,
|
|
33
|
-
it never buys silence. Quiet stretches get heartbeats with elapsed time.
|
|
34
|
-
- Each dev server a command starts gets its tmux log-tail window at launch time
|
|
35
|
-
(window creation is launch-coupled; users re-create separately when they close one).
|
|
36
|
-
|
|
37
|
-
## 3. Summaries state outcomes
|
|
38
|
-
The final line says what actually happened: target device, what the tier meant,
|
|
39
|
-
resulting state — never a bare status word. Dev-override runs are marked
|
|
40
|
-
(`[dev: MM_HARNESS_BIN]`) so it is always evident which bin served.
|
|
41
|
-
|
|
42
|
-
## 4. Dev and prod are explicit
|
|
43
|
-
The global install is prod (`mm-harness`); a dev checkout runs via the documented
|
|
44
|
-
`MM_HARNESS_BIN` switch (conventionally aliased `mmdev-harness`). The dev override
|
|
45
|
-
announces itself in help and summaries. Completions cover both names.
|
|
46
|
-
|
|
47
|
-
## 5. Errors teach the exact escape
|
|
48
|
-
Every failure states the next command for the caller's actual situation. A wrong
|
|
49
|
-
hint (an escape for a different failure mode) is a bug of the same severity as
|
|
50
|
-
the failure itself.
|
|
51
|
-
|
|
52
|
-
## 6. Lifecycle verbs are symmetric and idempotent
|
|
53
|
-
What a command starts, a sibling verb stops (`launch`/`stop`), scoped to what this
|
|
54
|
-
checkout owns (port-scoped, session-scoped) — never "whatever is running".
|
|
55
|
-
Nothing-to-do is success. Tests never leak into the operator's real tmux.
|
|
56
|
-
|
|
57
|
-
## 7. Color is consistent and optional
|
|
58
|
-
All human output styles through `cli-color.ts` (headers, ok/warn/err states,
|
|
59
|
-
provenance, "Next:" hints); `NO_COLOR`/non-TTY degrade to plain text. No surface
|
|
60
|
-
invents its own ANSI.
|
|
61
|
-
|
|
62
|
-
## 8. Doctor is the status surface
|
|
63
|
-
`doctor` reports, per platform: live runtime state (deps currency, dev-server
|
|
64
|
-
up/stale on the slot's resolved port, app/browser presence), the scoped runtime
|
|
65
|
-
context with provenance (`[file]`/`[env]`/`[default]`), and the exact customize
|
|
66
|
-
hint per row. Read-only unless `--fix`.
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# Video demo validation
|
|
2
|
-
|
|
3
|
-
Use this checklist against the installed release before recording. Each checkout
|
|
4
|
-
auto-detects its platform, ports, and slot; the paths below are placeholders only.
|
|
5
|
-
|
|
6
|
-
```bash
|
|
7
|
-
export EXTENSION_CHECKOUT=/path/to/metamask-extension
|
|
8
|
-
export MOBILE_CHECKOUT=/path/to/metamask-mobile
|
|
9
|
-
export CORE_CHECKOUT=/path/to/core
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## Common
|
|
13
|
-
|
|
14
|
-
- [ ] `mm-harness --version` prints the intended release.
|
|
15
|
-
- [ ] `mm-harness doctor` explains any unavailable capability and gives one next step.
|
|
16
|
-
- [ ] Recipe results print diagnostics and absolute artifact paths inline.
|
|
17
|
-
- [ ] `git status --short` is unchanged in each product checkout after validation.
|
|
18
|
-
|
|
19
|
-
## Extension
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
cd "$EXTENSION_CHECKOUT"
|
|
23
|
-
mm-harness launch --build --verify
|
|
24
|
-
mm-harness doctor
|
|
25
|
-
mm-harness actions positions
|
|
26
|
-
mm-harness flows
|
|
27
|
-
mm-harness run runner.smoke --artifacts-dir temp/demo
|
|
28
|
-
mm-harness run wallet.smoke --artifacts-dir temp/wallet-demo
|
|
29
|
-
mm-harness logs --source app
|
|
30
|
-
mm-harness debug
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
- [ ] Launch keeps an incremental webpack watcher alive.
|
|
34
|
-
- [ ] Two small source edits compile incrementally; browser refresh shows both changes.
|
|
35
|
-
- [ ] `debug` connects to the active slot's MetaMask target and opens Console.
|
|
36
|
-
- [ ] `logs --source app` shows extension logs; `--source dapp` and `--source webpack`
|
|
37
|
-
show their separate streams.
|
|
38
|
-
- [ ] Each recipe prints `diagnostics: CLEAN` or expands every warning/error inline.
|
|
39
|
-
- [ ] Each recipe prints absolute paths for its report, trace, diagnostics, screenshots,
|
|
40
|
-
and artifact manifest.
|
|
41
|
-
|
|
42
|
-
## Mobile
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
cd "$MOBILE_CHECKOUT"
|
|
46
|
-
mm-harness launch ios --verify
|
|
47
|
-
mm-harness fixtures set
|
|
48
|
-
mm-harness call metamask.wallet.ensure_unlocked
|
|
49
|
-
mm-harness status
|
|
50
|
-
mm-harness logs --source app
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
- [ ] The intended simulator is running; focus changes only when explicitly requested.
|
|
54
|
-
- [ ] Fixture setup reads the canonical checkout fixture and unlocks the wallet.
|
|
55
|
-
- [ ] Status reports the live route, wallet state, account, and fixture readiness.
|
|
56
|
-
- [ ] App logs are separate from Metro logs (`mm-harness logs --source metro`).
|
|
57
|
-
|
|
58
|
-
## Core
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
cd "$CORE_CHECKOUT"
|
|
62
|
-
mm-harness doctor
|
|
63
|
-
mm-harness run runner.smoke --artifacts-dir temp/demo
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
- [ ] Doctor reports the headless controller ready.
|
|
67
|
-
- [ ] The canonical wallet fixture supplies the default account.
|
|
68
|
-
- [ ] Evidence paths are absolute; diagnostics is explicitly `N/A` for headless Core.
|
|
69
|
-
|
|
70
|
-
## Recording path
|
|
71
|
-
|
|
72
|
-
Show the Extension discovery and proof commands, then the equivalent Mobile and Core
|
|
73
|
-
commands. The useful story is: one auto-detected CLI, reusable team libraries,
|
|
74
|
-
parameterized recipes, app diagnostics, and proof artifacts that a human can inspect.
|
package/docs/architecture.md
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# Architecture
|
|
2
|
-
|
|
3
|
-
`mm-harness` is the MetaMask adapter and CLI over the generic Recipe Protocol
|
|
4
|
-
engine. Control flows downward only:
|
|
5
|
-
|
|
6
|
-
```text
|
|
7
|
-
bin/mm-harness
|
|
8
|
-
→ src/ typed CLI, decisions, orchestration, evidence
|
|
9
|
-
→ @farmslot/recipe-harness generic graph execution and transports
|
|
10
|
-
→ @farmslot/protocol recipe, manifest, trace, artifact schemas
|
|
11
|
-
→ adapters/ focused OS, browser, simulator, and device leaves
|
|
12
|
-
→ library/ MetaMask actions, flows, recipes, manifests
|
|
13
|
-
→ MetaMask checkout app under test
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
Nothing under `adapters/` or `library/` calls back into `mm-harness`. TypeScript
|
|
17
|
-
owns sequencing; a leaf performs one platform operation and exits; the library
|
|
18
|
-
defines composable behavior.
|
|
19
|
-
|
|
20
|
-
## Ownership
|
|
21
|
-
|
|
22
|
-
| Layer | Owns | Does not own |
|
|
23
|
-
|---|---|---|
|
|
24
|
-
| `@farmslot/protocol` | Recipe and evidence schemas | execution or product behavior |
|
|
25
|
-
| `@farmslot/recipe-harness` | graph execution, generic `ui.*`, traces and artifacts | MetaMask behavior |
|
|
26
|
-
| this package | MetaMask actions, runtime control, CLI, diagnostics | task acceptance criteria or copied engine logic |
|
|
27
|
-
| skills/checklists | task workflow and proof expectations | runtime or runner implementation |
|
|
28
|
-
| product checkout | application and explicit debug hooks | harness scripts or private workflow logic |
|
|
29
|
-
|
|
30
|
-
A capability reusable without MetaMask belongs in the generic engine. A durable
|
|
31
|
-
MetaMask operation belongs here. Ticket-specific assertions stay in the task's
|
|
32
|
-
recipe or checklist.
|
|
33
|
-
|
|
34
|
-
## Repository layout
|
|
35
|
-
|
|
36
|
-
| Path | Responsibility |
|
|
37
|
-
|---|---|
|
|
38
|
-
| `bin/mm-harness` | one public executable |
|
|
39
|
-
| `src/commands/` | public command behavior |
|
|
40
|
-
| `src/adapters/` | typed product decisions and orchestration |
|
|
41
|
-
| `adapters/<platform>/` | focused shell/Node runtime leaves |
|
|
42
|
-
| `adapters/shared/` | cross-platform OS glue |
|
|
43
|
-
| `adapters/*/overlay/` | the only files installed or patched into a checkout |
|
|
44
|
-
| `library/actions/` | executable MetaMask action adapters |
|
|
45
|
-
| `library/flows/` | reusable parameterized behavior |
|
|
46
|
-
| `library/recipes/` | reusable proof recipes |
|
|
47
|
-
| `library/manifests/` | declared capability surface |
|
|
48
|
-
| `scripts/` | repository development checks only |
|
|
49
|
-
|
|
50
|
-
All TypeScript belongs under `src/`. New standalone runtime helpers use ESM
|
|
51
|
-
unless their host runtime requires CommonJS. Shell remains limited to operations
|
|
52
|
-
that genuinely need shell/device tools.
|
|
53
|
-
|
|
54
|
-
## Runtime isolation
|
|
55
|
-
|
|
56
|
-
Each checkout owns its runtime state:
|
|
57
|
-
|
|
58
|
-
```text
|
|
59
|
-
temp/recipe/runtime/ ports, processes, fixture, logs, runtime identity
|
|
60
|
-
temp/recipe/harness/ installed runtime overlay
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Defaults live in `adapters/shared/path-defaults.json`. Every browser profile,
|
|
64
|
-
simulator/device selection, port, watcher, and evidence directory must resolve
|
|
65
|
-
from the current checkout so parallel slots do not share state.
|
|
66
|
-
|
|
67
|
-
Extension uses an isolated Chrome profile and CDP port. Its normal watcher builds
|
|
68
|
-
to product `dist/chrome`, then synchronizes successful output into the isolated
|
|
69
|
-
runtime extension. Mobile owns an isolated Metro/device identity. Core remains
|
|
70
|
-
headless.
|
|
71
|
-
|
|
72
|
-
## Proof boundary
|
|
73
|
-
|
|
74
|
-
`launch` prepares the runtime. `run` validates and executes a recipe through the
|
|
75
|
-
generic engine. Runtime setup may seed declared fixtures before proof begins;
|
|
76
|
-
proof actions must not mutate hidden product state to fabricate a result.
|
|
77
|
-
|
|
78
|
-
Each run produces a summary, trace, diagnostics where applicable, and an artifact
|
|
79
|
-
manifest. Application warnings/errors are side findings unless a recipe assertion
|
|
80
|
-
turns them into a proof failure.
|
|
81
|
-
|
|
82
|
-
## Change checks
|
|
83
|
-
|
|
84
|
-
- Put the change in the owning layer; do not duplicate behavior in a skill or leaf.
|
|
85
|
-
- Keep actions parameterized and manifests honest.
|
|
86
|
-
- Validate the machine contract and the visible human outcome.
|
|
87
|
-
- Exercise affected platforms on real checkouts when runtime behavior changes.
|
|
88
|
-
- Run `yarn check` and update `CHANGELOG.md` for user-visible changes.
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
# Live Adapter Contract
|
|
2
|
-
|
|
3
|
-
The MetaMask runner implements Recipe Protocol v1 through the shared recipe
|
|
4
|
-
harness package. Project-specific live behavior is supplied by
|
|
5
|
-
manifest-declared action adapters.
|
|
6
|
-
|
|
7
|
-
Official `ui.*` semantics are implemented by
|
|
8
|
-
`createStandardUiAdapters({ transport })` plus shared CDP/React Native base
|
|
9
|
-
transports. The MetaMask runner supplies only tiny runtime bindings that point
|
|
10
|
-
those base transports at the Extension CDP page or Mobile React Native bridge.
|
|
11
|
-
MetaMask-specific actions remain separate manifest-declared live adapters.
|
|
12
|
-
|
|
13
|
-
For actions that must prove real product behavior, especially `metamask.perps.*`, static placeholders are refused by default. A live adapter script must exist in one of these locations. Domain-grouped paths are preferred so code ownership stays obvious:
|
|
14
|
-
|
|
15
|
-
```text
|
|
16
|
-
$METAMASK_RECIPE_LIVE_ADAPTER_DIR/<platform>/<domain>/<action-local-name>.mjs
|
|
17
|
-
$METAMASK_RECIPE_LIVE_ADAPTER_DIR/shared/<domain>/<action-local-name>.mjs
|
|
18
|
-
<runner>/library/actions/<platform>/<domain>/<action-local-name>.mjs
|
|
19
|
-
<runner>/library/actions/shared/<domain>/<action-local-name>.mjs
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Action adapters are grouped `.mjs` modules. Flat files, CommonJS, and shell
|
|
23
|
-
adapters are not part of the contract. Do not add `ui.*` files here; official UI
|
|
24
|
-
actions go through shared base transports. Examples:
|
|
25
|
-
|
|
26
|
-
```text
|
|
27
|
-
library/actions/extension/perps/ensure_positions.mjs
|
|
28
|
-
library/actions/extension/perps/close_positions.mjs
|
|
29
|
-
library/actions/extension/perps/close_orders.mjs
|
|
30
|
-
library/actions/mobile/perps/place_order.mjs
|
|
31
|
-
library/actions/mobile/wallet/ensure_unlocked.mjs
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
The runner invokes the script with one argument: a JSON input file path. The same path is also available as `METAMASK_RECIPE_ADAPTER_INPUT`. The script must write JSON to `outputPath` from the input document, or print JSON to stdout.
|
|
35
|
-
|
|
36
|
-
Input shape:
|
|
37
|
-
|
|
38
|
-
```json
|
|
39
|
-
{
|
|
40
|
-
"schemaVersion": 1,
|
|
41
|
-
"platform": "mobile|extension",
|
|
42
|
-
"action": "metamask.perps.ensure_positions",
|
|
43
|
-
"node": {},
|
|
44
|
-
"context": {
|
|
45
|
-
"nodeId": "ensure-clean",
|
|
46
|
-
"projectRoot": "/path/to/product",
|
|
47
|
-
"artifactsDir": "/path/to/artifacts"
|
|
48
|
-
},
|
|
49
|
-
"outputPath": "/tmp/.../output.json"
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Output shape is action-specific, but must be redacted and suitable for `trace.json`. If the adapter captures evidence files, write them under `context.artifactsDir` and return relative artifact paths for the runner adapter to index in a follow-up implementation.
|
|
54
|
-
|
|
55
|
-
Proof rule: live adapters must drive real supported app/API paths. They must not write directly into UI state, DOM state, React/Redux/MobX state, local storage, controller internals, or any mid-recipe state that fabricates the proof condition.
|
|
56
|
-
|
|
57
|
-
## Controller/API calls vs visible UI proof
|
|
58
|
-
|
|
59
|
-
Recipe authors should choose the layer based on what must be proven:
|
|
60
|
-
|
|
61
|
-
| Need | Use | Rule |
|
|
62
|
-
|---|---|---|
|
|
63
|
-
| Fast reproducible setup/teardown before or after the proof window | `metamask.*` domain actions such as `start_state`, `ensure_positions`, `close_orders` | May use supported product/controller APIs, but must read/assert the final state. |
|
|
64
|
-
| Read-only state proof | `metamask.*.read_*` or `metamask.*.assert_*` | Must return redacted live state in trace output. |
|
|
65
|
-
| Human-visible acceptance criterion | official `ui.*` actions | Drive the actual visible path: press/tap, input/keypad, scroll into view, screenshot. Do not replace it with a controller call. |
|
|
66
|
-
| Ticket-specific visual detail | task-local recipe assertions/evidence | Do not add a reusable action only for one ticket. |
|
|
67
|
-
|
|
68
|
-
## Shared action-surface boundaries
|
|
69
|
-
|
|
70
|
-
The manifest is a durable capability contract, not a place to encode one
|
|
71
|
-
ticket's acceptance criteria. Do not add shared `metamask.*` actions for ticket
|
|
72
|
-
IDs, POCs, exact test IDs, exact copy, styling, placement, or other one-off UI
|
|
73
|
-
proof needs.
|
|
74
|
-
|
|
75
|
-
Use:
|
|
76
|
-
|
|
77
|
-
- official `ui.*` actions for reusable presence, input, scroll, and screenshot
|
|
78
|
-
behavior;
|
|
79
|
-
- screenshot `claims` for visual, copy, and layout proof;
|
|
80
|
-
- task-local composed flows under the task artifact directory when a ticket
|
|
81
|
-
needs a reusable helper for that ticket only;
|
|
82
|
-
- safe direct CDP/controller calls for read/assert or supported setup paths,
|
|
83
|
-
never state fabrication.
|
|
84
|
-
|
|
85
|
-
Add or keep a shared action only when it represents a durable parameterized
|
|
86
|
-
domain capability useful across many tasks, such as `metamask.perps.start_state`,
|
|
87
|
-
`metamask.perps.place_order`, `metamask.perps.close_positions`, or
|
|
88
|
-
`metamask.perps.assert_positions`.
|
|
89
|
-
|
|
90
|
-
`ui.scroll` is part of the current executable contract and runner.action-validation must
|
|
91
|
-
prove both normal scrolling and `scroll_into_view` before screenshot capture.
|
|
92
|
-
`ui.gesture` is intentionally not advertised yet; drag/swipe proof must wait
|
|
93
|
-
until the shared runtime and this runner expose and validate that action on both
|
|
94
|
-
platforms.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
## Flow catalog follow-up
|
|
99
|
-
|
|
100
|
-
Action adapters fulfill one manifest-declared operation. Production recipes should also be able to call domain flow catalogs that compose these operations into idempotent `ensure_*` start states. These flows are owned by this runner/domain layer, not by shared runtime packages or wrapper glue.
|
|
101
|
-
|
|
102
|
-
For Perps, recipes should use the runner-provided `metamask.perps.start_state({ network, provider, page, market, positions, orders })` and `metamask.perps.teardown_state(...)` actions as the default reproducibility boundary. These actions compose primitive bulk operations such as `close_positions({ mode: "all" })` and `close_orders({ mode: "all" })` instead of multiplying one-off cleanup actions.
|
|
103
|
-
|
|
104
|
-
## Built-in Extension live adapters
|
|
105
|
-
|
|
106
|
-
The first Extension adapter set is bundled under `library/actions/extension/` and talks directly to the Chrome extension page target over CDP. It does not execute a second recipe graph. The v1 runner still owns workflow traversal; each script only fulfills one manifest-declared action.
|
|
107
|
-
|
|
108
|
-
Runtime input:
|
|
109
|
-
|
|
110
|
-
```text
|
|
111
|
-
node.cdp_port | CDP_PORT | RECIPE_CDP_PORT
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Optional autolaunch input for existing Extension builds:
|
|
115
|
-
|
|
116
|
-
```text
|
|
117
|
-
METAMASK_RECIPE_EXTENSION_AUTOLAUNCH=1
|
|
118
|
-
METAMASK_RECIPE_EXTENSION_LAUNCH_EXISTING_DIST=1
|
|
119
|
-
node.launch_existing_dist=true
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
When enabled, the adapter reuses the requested CDP port if a compatible extension target exists; otherwise it launches Chrome from the target checkout's existing `dist/chrome` without rebuilding the product. The runtime copy, profile, logs, and `runtime.json` are written under `context.artifactsDir/extension-runtime/`.
|
|
123
|
-
|
|
124
|
-
CLI equivalent:
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
mm-harness run <recipe.json> --adapter extension --cdp-port 6664 --launch-existing-dist --artifacts-dir <dir>
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
The CLI maps `--cdp-port` to `CDP_PORT`/`RECIPE_CDP_PORT` and maps `--launch-existing-dist` to `METAMASK_RECIPE_EXTENSION_AUTOLAUNCH=1` for the duration of the recipe run.
|
|
131
|
-
|
|
132
|
-
Currently implemented Extension actions:
|
|
133
|
-
|
|
134
|
-
```text
|
|
135
|
-
ui.navigate # extension: page alias or hash/path/url
|
|
136
|
-
metamask.perps.read_positions
|
|
137
|
-
metamask.perps.read_orders
|
|
138
|
-
metamask.perps.close_positions # primitive bulk close selected positions
|
|
139
|
-
metamask.perps.close_orders # primitive bulk cancel selected orders
|
|
140
|
-
metamask.perps.place_order
|
|
141
|
-
metamask.perps.assert_positions
|
|
142
|
-
metamask.perps.assert_orders
|
|
143
|
-
metamask.perps.ensure_positions # high-level read/close/place/assert wrapper
|
|
144
|
-
metamask.perps.ensure_orders # high-level read/cancel/assert wrapper
|
|
145
|
-
ui.press
|
|
146
|
-
ui.scroll
|
|
147
|
-
ui.wait_for
|
|
148
|
-
ui.screenshot
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Navigation supports a small discoverable `page` alias set (`home`, `perps`, `perps-market`) plus raw extension hash/url fallback. Check the action manifest before hardcoding routes.
|
|
152
|
-
|
|
153
|
-
Task-specific UI styling checks, such as one ticket proving a banner color or placement, must not be implemented as reusable `metamask.perps.*` actions. Use official `ui.wait_for` for reusable presence/absence checks plus screenshot/task-local validation evidence for that ticket.
|
|
154
|
-
|
|
155
|
-
Read-only position checks use `stateHooks.submitRequestToBackground('perpsGetPositions', [{ skipCache: true }])`. State-changing actions prefer UI interaction through CDP mouse/keyboard events. Bulk cleanup primitives may call product background APIs such as `perpsClosePositions` or `perpsCancelOrders` when the UI control is unavailable; this is a supported app/API path, not direct state mutation. Adapters must not mutate Redux/React state, DOM state, local storage, or controller internals to fabricate proof.
|
|
156
|
-
|
|
157
|
-
## Built-in Mobile live adapters
|
|
158
|
-
|
|
159
|
-
The Mobile adapter is bundled under `library/actions/mobile/`. Its CDP bridge, wallet setup, target discovery, and screenshot helpers run from the runner runtime; the Mobile checkout must not own harness control scripts. The app still needs a development-only in-app bridge/HUD overlay when a historical checkout does not expose the required `globalThis.__AGENTIC__` hooks.
|
|
160
|
-
|
|
161
|
-
Runtime input:
|
|
162
|
-
|
|
163
|
-
```text
|
|
164
|
-
node.watcher_port | node.metro_port | node.cdp_port | WATCHER_PORT | CDP_PORT | RECIPE_CDP_PORT
|
|
165
|
-
node.simulator | node.ios_simulator | IOS_SIMULATOR
|
|
166
|
-
node.android_device | ANDROID_DEVICE
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
Currently implemented Mobile actions:
|
|
170
|
-
|
|
171
|
-
```text
|
|
172
|
-
ui.navigate # mobile: page alias or route/screen + params
|
|
173
|
-
metamask.perps.read_positions
|
|
174
|
-
metamask.perps.read_orders
|
|
175
|
-
metamask.perps.close_positions # primitive bulk close selected positions
|
|
176
|
-
metamask.perps.close_orders # primitive bulk cancel selected orders
|
|
177
|
-
metamask.perps.place_order
|
|
178
|
-
metamask.perps.assert_positions
|
|
179
|
-
metamask.perps.assert_orders
|
|
180
|
-
metamask.perps.ensure_positions # high-level read/close/place/assert wrapper
|
|
181
|
-
metamask.perps.ensure_orders # high-level read/cancel/assert wrapper
|
|
182
|
-
ui.press
|
|
183
|
-
ui.scroll
|
|
184
|
-
ui.wait_for
|
|
185
|
-
ui.screenshot
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
Navigation supports a small discoverable `page` alias set (`home`, `perps`, `perps-market`) plus raw React Navigation route/params fallback. Check the action manifest before hardcoding routes.
|
|
189
|
-
|
|
190
|
-
Read-only position checks use `Engine.context.PerpsController.getPositions()` through Hermes CDP. State-changing Perps actions use supported controller APIs (`placeOrder`, `closePositions`) through the same app bridge rather than mutating Redux/React/local storage. Mobile `ui.press` uses `press-test-id` for `test_id`/`testID`/`selector` and `press-text` for visible `text`; scrolling uses `scroll-view`. Screenshot capture uses `xcrun simctl io <simulator> screenshot` for iOS simulator proof.
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# Package Boundaries
|
|
2
|
-
|
|
3
|
-
This package intentionally stays as **one npm package** with a clear internal
|
|
4
|
-
split. Splitting into two packages now would make users choose between packages
|
|
5
|
-
before the runtime API is stable. Instead, keep one install surface and separate
|
|
6
|
-
responsibilities inside the repo.
|
|
7
|
-
|
|
8
|
-
## Internal split
|
|
9
|
-
|
|
10
|
-
| Area | Owns | Does not own |
|
|
11
|
-
|---|---|---|
|
|
12
|
-
| Recipe layer | Action manifests, reusable recipes, typed runner binding, Mobile/Extension live adapters, proof semantics. | Starting Metro/Chrome, simulator boot, native builds, git cleanup. |
|
|
13
|
-
| Runtime lifecycle layer | Harness install/cleanup, Metro/dev-client launch, bundle prewarm, Chrome/CDP launch, fixture/profile setup, readiness gates. | Recipe graph execution, action vocabulary decisions, task-specific proof logic. |
|
|
14
|
-
|
|
15
|
-
## Stable command contract
|
|
16
|
-
|
|
17
|
-
Keep the public package simple:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
mm-harness launch ios ... # runtime lifecycle, then readiness proof (mobile)
|
|
21
|
-
mm-harness launch ... # runtime lifecycle, then readiness proof (extension)
|
|
22
|
-
mm-harness run <recipe.json> ... # recipe execution only
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Wrappers such as skills or slot farms should call those commands. They should not
|
|
26
|
-
copy adapter scripts or reimplement Metro/Chrome launch behavior.
|
|
27
|
-
|
|
28
|
-
## Why not two packages yet?
|
|
29
|
-
|
|
30
|
-
A future split may be useful, for example:
|
|
31
|
-
|
|
32
|
-
- `@metamask/recipe-runner` for manifests/adapters/proof execution;
|
|
33
|
-
- `@metamask/recipe-runtime` for Mobile/Extension sandbox launch.
|
|
34
|
-
|
|
35
|
-
Do that only after the runtime CLI is stable, all wrappers call it exclusively
|
|
36
|
-
(no copied adapter scripts), and the two areas have gone several releases
|
|
37
|
-
without a change that touches both. Until then, two packages would likely
|
|
38
|
-
increase confusion and version skew.
|
|
39
|
-
|
|
40
|
-
## Change discipline
|
|
41
|
-
|
|
42
|
-
1. Prefer moving behavior into the runner before changing farms/skills.
|
|
43
|
-
2. Keep compatibility wrappers when renaming files or commands.
|
|
44
|
-
3. Validate both paths after runtime changes:
|
|
45
|
-
- direct runner/skill path;
|
|
46
|
-
- Farmslot/Command Center prepare path.
|
|
47
|
-
4. Do not move files just for tidiness if callers still depend on old paths.
|