@deeeed/metamask-harness 0.28.0 → 0.29.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +41 -0
  3. package/adapters/extension/build-lavamoat.sh +2 -1
  4. package/adapters/extension/ensure-browser.sh +82 -9
  5. package/adapters/extension/inject.mjs +1 -0
  6. package/adapters/extension/launch-browser.cjs +83 -1
  7. package/adapters/extension/lib/chrome-args.cjs +325 -1
  8. package/adapters/extension/lib/playwright-cdp.cjs +34 -0
  9. package/adapters/extension/lib/slot-title.cjs +2 -4
  10. package/adapters/extension/lib/validation-launch-supervisor.cjs +292 -0
  11. package/adapters/extension/lib/validation-process-ownership.cjs +69 -0
  12. package/adapters/extension/reattach.sh +2 -1
  13. package/adapters/extension/sidepanel-toggle.sh +14 -96
  14. package/adapters/extension/wallet-fixture-state.cjs +8 -31
  15. package/adapters/manifest.json +16 -0
  16. package/adapters/shared/private-atomic-write.cjs +47 -0
  17. package/adapters/shared/setup-base.sh +864 -0
  18. package/dist/adapters/extension/runtime.js +367 -24
  19. package/dist/adapters/extension/validation-process-ownership.js +10 -0
  20. package/dist/cli-commands.js +1 -0
  21. package/dist/command-contract.js +12 -0
  22. package/dist/commands/launch/extension.js +130 -19
  23. package/dist/commands/setup-base.js +24 -0
  24. package/dist/mm-harness-cli.js +28 -2
  25. package/docs/RECIPES.md +26 -1
  26. package/docs/SECURITY.md +31 -0
  27. package/library/actions/extension/analytics/consent.mjs +203 -0
  28. package/library/actions/extension/analytics/set_consent.mjs +19 -143
  29. package/library/actions/extension/perps/perps.mjs +2 -16
  30. package/library/actions/extension/perps/state.mjs +20 -0
  31. package/library/actions/extension/wallet/list_accounts.mjs +3 -25
  32. package/library/actions/extension/wallet/read_state.mjs +3 -23
  33. package/library/actions/extension/wallet/select_account.mjs +6 -33
  34. package/library/actions/extension/wallet/setup.mjs +2 -20
  35. package/library/actions/extension/wallet/state.mjs +111 -0
  36. package/library/recipes/runner/action-validation.extension.recipe.json +1 -1
  37. package/library/recipes/runner/action-validation.mobile.recipe.json +1 -1
  38. package/package.json +7 -4
  39. package/scripts/site-contrast.mjs +538 -0
  40. package/site/architecture.html +474 -0
  41. package/site/assets/progress.mjs +272 -0
  42. package/site/assets/style.css +808 -0
  43. package/site/cheatsheet.html +305 -0
  44. package/site/index.html +647 -0
  45. package/site/recipes.html +396 -0
  46. package/site/reviewers.html +374 -0
  47. package/site/tutorials/index.html +180 -0
  48. package/site/tutorials/v1.html +211 -0
  49. package/site/tutorials/v2.html +207 -0
  50. package/site/tutorials/v3.html +214 -0
  51. package/site/tutorials/v4.html +195 -0
  52. package/site/tutorials/v5.html +163 -0
  53. package/site/tutorials/v6.html +165 -0
  54. package/site/tutorials/v7.html +184 -0
@@ -0,0 +1,305 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Cheatsheet — mm-harness</title>
7
+ <meta name="description" content="Every mm-harness command worth knowing, filterable by platform, with copy buttons.">
8
+ <link rel="stylesheet" href="assets/style.css">
9
+ </head>
10
+ <body data-progress-page="cheatsheet">
11
+ <a class="skip" href="#daily">Skip to the commands</a>
12
+
13
+ <header class="topbar">
14
+ <div class="wrap-wide topbar-inner">
15
+ <a class="brand" href="index.html">
16
+ <span class="brand-mark" aria-hidden="true"></span>
17
+ <span class="brand-name">mm-harness</span>
18
+ </a>
19
+ <nav class="nav" aria-label="Main">
20
+ <a href="index.html">Start Here</a>
21
+ <a href="recipes.html">Recipes</a>
22
+ <a href="cheatsheet.html" aria-current="page">Cheatsheet</a>
23
+ <a href="architecture.html">Architecture</a>
24
+ <a href="tutorials/index.html">Tutorials</a>
25
+ <a href="reviewers.html">For Reviewers</a>
26
+ </nav>
27
+ </div>
28
+ </header>
29
+
30
+ <main>
31
+ <section class="wrap-wide hero" style="padding-bottom:1rem">
32
+ <span class="eyebrow">Reference</span>
33
+ <h1>Cheatsheet</h1>
34
+ <p class="lede">
35
+ <code>mm-harness &lt;command&gt; [target] [flags]</code> — run it from inside any MetaMask checkout.
36
+ The product is auto-detected; the positional target forces it; everything else is a flag on the
37
+ same command. Filter by what you actually work on.
38
+ </p>
39
+ <div class="hero-meta">
40
+ <span>mm-harness 0.26+</span>
41
+ <span>one bin, 20 commands</span>
42
+ <span>--json on everything</span>
43
+ </div>
44
+ </section>
45
+
46
+ <section class="wrap-wide">
47
+ <div class="filters">
48
+ <span class="filter-label">Platform</span>
49
+ <button type="button" class="chip" data-platform="all" aria-pressed="true">Everything</button>
50
+ <button type="button" class="chip" data-platform="extension" aria-pressed="false">Extension</button>
51
+ <button type="button" class="chip" data-platform="mobile" aria-pressed="false">Mobile</button>
52
+ <button type="button" class="chip" data-platform="core" aria-pressed="false">Core</button>
53
+ </div>
54
+
55
+ <div data-filter-section>
56
+ <h2 id="daily">Daily loop</h2>
57
+ <p>What you run many times a day. The overlay is auto-ensured; you do not install it by hand.</p>
58
+ <div class="table-scroll" data-copy-cells>
59
+ <table>
60
+ <thead><tr><th>Situation</th><th>Command</th></tr></thead>
61
+ <tbody>
62
+ <tr data-platforms="all"><td>Where am I, what is live, what is next</td><td><code>mm-harness status</code></td></tr>
63
+ <tr data-platforms="all"><td>…without waiting for live probes</td><td><code>mm-harness status --fast</code></td></tr>
64
+ <tr data-platforms="extension"><td>Launch the extension (fullscreen)</td><td><code>mm-harness launch</code></td></tr>
65
+ <tr data-platforms="extension"><td>Launch into the sidepanel</td><td><code>mm-harness launch --sidepanel</code></td></tr>
66
+ <tr data-platforms="extension"><td>Launch beside a dapp</td><td><code>mm-harness launch --sidepanel --url &lt;dapp-url&gt;</code></td></tr>
67
+ <tr data-platforms="mobile"><td>Start / relaunch iOS</td><td><code>mm-harness launch ios</code></td></tr>
68
+ <tr data-platforms="mobile"><td>Start / relaunch Android</td><td><code>mm-harness launch android</code></td></tr>
69
+ <tr data-platforms="mobile"><td>Pick the device explicitly</td><td><code>mm-harness launch ios --device &lt;udid|name&gt;</code></td></tr>
70
+ <tr data-platforms="extension mobile"><td>Native or bundler output changed — clean build</td><td><code>mm-harness launch --build</code></td></tr>
71
+ <tr data-platforms="extension mobile"><td>Launch, then wait until it is genuinely ready</td><td><code>mm-harness launch --verify</code></td></tr>
72
+ <tr data-platforms="extension mobile"><td>Tail the dev server and app logs</td><td><code>mm-harness logs</code></td></tr>
73
+ <tr data-platforms="extension mobile"><td>Stop what this checkout owns</td><td><code>mm-harness stop</code></td></tr>
74
+ <tr data-platforms="extension"><td>Open Chrome DevTools over CDP</td><td><code>mm-harness debug</code></td></tr>
75
+ <tr data-platforms="extension"><td>Service-worker DevTools</td><td><code>mm-harness debug --worker</code></td></tr>
76
+ <tr data-platforms="mobile"><td>Open React Native DevTools</td><td><code>mm-harness debug</code></td></tr>
77
+ <tr data-platforms="mobile"><td>Open the RN developer menu</td><td><code>mm-harness debug --dev-menu</code></td></tr>
78
+ </tbody>
79
+ </table>
80
+ </div>
81
+ <p class="step-why" style="font-size:.92rem">
82
+ <code>stop</code> is scoped to this checkout, so parallel checkouts are untouched, and it is
83
+ idempotent — stopping nothing is success.
84
+ </p>
85
+ </div>
86
+
87
+ <div data-filter-section>
88
+ <h2 id="discover">Discover</h2>
89
+ <p>
90
+ You never guess capabilities. These commands print what exists; anything not listed does not
91
+ exist for this checkout.
92
+ </p>
93
+ <div class="table-scroll" data-copy-cells>
94
+ <table>
95
+ <thead><tr><th>Situation</th><th>Command</th></tr></thead>
96
+ <tbody>
97
+ <tr data-platforms="all"><td>Every action available here</td><td><code>mm-harness actions</code></td></tr>
98
+ <tr data-platforms="all"><td>Just the categories and counts</td><td><code>mm-harness actions --categories</code></td></tr>
99
+ <tr data-platforms="extension mobile"><td>One UI category</td><td><code>mm-harness actions --category ui</code></td></tr>
100
+ <tr data-platforms="all"><td>Search (typo-tolerant)</td><td><code>mm-harness actions positions</code></td></tr>
101
+ <tr data-platforms="extension mobile"><td>One wallet action's fields, in detail</td><td><code>mm-harness actions --action read_state</code></td></tr>
102
+ <tr data-platforms="core"><td>One Core action's fields, in detail</td><td><code>mm-harness actions --action read_positions</code></td></tr>
103
+ <tr data-platforms="all"><td>What <code>call</code> accepts here</td><td><code>mm-harness call --list</code></td></tr>
104
+ <tr data-platforms="all"><td>Recipes you can run here</td><td><code>mm-harness run --list</code></td></tr>
105
+ <tr data-platforms="all"><td>What a recipe does before running it</td><td><code>mm-harness run &lt;recipe&gt; --describe</code></td></tr>
106
+ <tr data-platforms="all"><td>The raw registry, for tooling</td><td><code>mm-harness actions --raw --json</code></td></tr>
107
+ </tbody>
108
+ </table>
109
+ </div>
110
+ </div>
111
+
112
+ <div data-filter-section>
113
+ <h2 id="drive">Drive one action</h2>
114
+ <p>
115
+ <code>call</code> runs a single action as a one-node recipe through the real engine path — the
116
+ same trace and evidence a full run produces. Short names resolve when unambiguous.
117
+ </p>
118
+ <div class="table-scroll" data-copy-cells>
119
+ <table>
120
+ <thead><tr><th>Situation</th><th>Command</th></tr></thead>
121
+ <tbody>
122
+ <tr data-platforms="extension mobile"><td>Read wallet state (redacted)</td><td><code>mm-harness call read_state</code></td></tr>
123
+ <tr data-platforms="extension mobile"><td>Unlock if locked</td><td><code>mm-harness call ensure_unlocked</code></td></tr>
124
+ <tr data-platforms="extension mobile"><td>Navigate by page intent</td><td><code>mm-harness call navigate page=perps</code></td></tr>
125
+ <tr data-platforms="extension mobile"><td>Press by visible text</td><td><code>mm-harness call press text="Account 1"</code></td></tr>
126
+ <tr data-platforms="extension mobile"><td>Capture a screenshot</td><td><code>mm-harness call screenshot path=proof.png</code></td></tr>
127
+ <tr data-platforms="all"><td>Run a shell command (every adapter)</td><td><code>mm-harness call command cmd="echo hi"</code></td></tr>
128
+ <tr data-platforms="extension mobile"><td>Pass a field the explicit way</td><td><code>mm-harness call navigate --arg page=perps</code></td></tr>
129
+ <tr data-platforms="extension mobile"><td>Keep wallet evidence somewhere you chose</td><td><code>mm-harness call read_state --artifacts-dir ./out</code></td></tr>
130
+ <tr data-platforms="core"><td>Keep Core evidence somewhere you chose</td><td><code>mm-harness call read_positions mode=all --artifacts-dir ./out</code></td></tr>
131
+ <tr data-platforms="mobile"><td>More than one device connected</td><td><code>mm-harness call read_state --device &lt;udid&gt;</code></td></tr>
132
+ </tbody>
133
+ </table>
134
+ </div>
135
+ </div>
136
+
137
+ <div data-filter-section>
138
+ <h2 id="prove">Prove — run recipes</h2>
139
+ <div class="table-scroll" data-copy-cells>
140
+ <table>
141
+ <thead><tr><th>Situation</th><th>Command</th></tr></thead>
142
+ <tbody>
143
+ <tr data-platforms="all"><td>Validate without touching anything (exit 5 if invalid)</td><td><code>mm-harness run &lt;recipe&gt; --plan</code></td></tr>
144
+ <tr data-platforms="all"><td>Execute and write evidence</td><td><code>mm-harness run &lt;recipe&gt;</code></td></tr>
145
+ <tr data-platforms="all"><td>Evidence in a directory you chose</td><td><code>mm-harness run &lt;recipe&gt; --artifacts-dir ./out</code></td></tr>
146
+ <tr data-platforms="all"><td>A recipe with parameters</td><td><code>mm-harness run perps.clean-market-testnet market=BTC</code></td></tr>
147
+ <tr data-platforms="all"><td>A recipe file on disk</td><td><code>mm-harness run ./my-recipe.json</code></td></tr>
148
+ <tr data-platforms="all"><td>Add a team recipe library</td><td><code>mm-harness run &lt;recipe&gt; --library perps=/path/to/library</code></td></tr>
149
+ <tr data-platforms="mobile"><td>Record video of the whole run</td><td><code>mm-harness run &lt;recipe&gt; --record-video=full-run</code></td></tr>
150
+ <tr data-platforms="all"><td>Streaming progress for an agent</td><td><code>mm-harness run &lt;recipe&gt; --json-stream</code></td></tr>
151
+ <tr data-platforms="all"><td>What did I last run, and how did it go</td><td><code>mm-harness last</code></td></tr>
152
+ </tbody>
153
+ </table>
154
+ </div>
155
+ <p class="step-why" style="font-size:.92rem">
156
+ iOS carries video; Extension capture is screenshots only. That asymmetry is real — do not promise
157
+ a reviewer a video of an extension run.
158
+ </p>
159
+ </div>
160
+
161
+ <div data-filter-section>
162
+ <h2 id="health">Health and repair</h2>
163
+ <div class="table-scroll" data-copy-cells>
164
+ <table>
165
+ <thead><tr><th>Situation</th><th>Command</th></tr></thead>
166
+ <tbody>
167
+ <tr data-platforms="all"><td>Full readiness check — no launch, read-only</td><td><code>mm-harness doctor</code></td></tr>
168
+ <tr data-platforms="all"><td>Repair runtime state without launching</td><td><code>mm-harness doctor --fix</code></td></tr>
169
+ <tr data-platforms="all"><td>Findings in machine form</td><td><code>mm-harness doctor --json</code></td></tr>
170
+ <tr data-platforms="all"><td>Is the overlay present and healthy</td><td><code>mm-harness verify</code></td></tr>
171
+ <tr data-platforms="all"><td>Install the overlay explicitly (CI, agents)</td><td><code>mm-harness install</code></td></tr>
172
+ <tr data-platforms="all"><td>Remove the overlay, restore the checkout</td><td><code>mm-harness cleanup</code></td></tr>
173
+ <tr data-platforms="mobile"><td>Install a cached dev client on a prepared simulator</td><td><code>mm-harness provision runway ios --adapter mobile</code></td></tr>
174
+ </tbody>
175
+ </table>
176
+ </div>
177
+ <p class="step-why" style="font-size:.92rem">
178
+ <code>doctor --fix</code> repairs what the harness owns. It will not launch the app, invent
179
+ credentials, or choose a wallet fixture — those need a human.
180
+ </p>
181
+ </div>
182
+
183
+ <div data-filter-section>
184
+ <h2 id="fixtures">Wallet fixtures</h2>
185
+ <p>
186
+ One canonical fixture per checkout, holding wallet <em>data</em> only. The password is read from
187
+ the fixture and never typed.
188
+ </p>
189
+ <div class="table-scroll" data-copy-cells>
190
+ <table>
191
+ <thead><tr><th>Situation</th><th>Command</th></tr></thead>
192
+ <tbody>
193
+ <tr data-platforms="extension mobile"><td>Status and the safe next command</td><td><code>mm-harness fixtures</code></td></tr>
194
+ <tr data-platforms="extension mobile"><td>Create from a fixture you already have</td><td><code>mm-harness fixtures init --from &lt;path&gt;</code></td></tr>
195
+ <tr data-platforms="extension mobile"><td>Create a disposable public test wallet</td><td><code>mm-harness fixtures init --dev</code></td></tr>
196
+ <tr data-platforms="extension mobile"><td>Apply it to the app (no typing)</td><td><code>mm-harness fixtures set</code></td></tr>
197
+ <tr data-platforms="extension mobile"><td>Refresh the fixture files on the target</td><td><code>mm-harness fixtures sync</code></td></tr>
198
+ <tr data-platforms="extension"><td>Render pre-launch profile state</td><td><code>mm-harness fixtures generate --fixture &lt;path&gt; --out &lt;path&gt;</code></td></tr>
199
+ </tbody>
200
+ </table>
201
+ </div>
202
+ <div class="note">
203
+ <span class="note-title">--dev wallets are disposable</span>
204
+ <p>A <code>--dev</code> fixture is a public test wallet. It must never hold real funds.</p>
205
+ </div>
206
+ </div>
207
+
208
+ <div data-filter-section>
209
+ <h2 id="repo">Repo checks</h2>
210
+ <div class="table-scroll" data-copy-cells>
211
+ <table>
212
+ <thead><tr><th>Situation</th><th>Command</th></tr></thead>
213
+ <tbody>
214
+ <tr data-platforms="all"><td>Lint/format/test just your diff</td><td><code>mm-harness check diff --profile fast</code></td></tr>
215
+ <tr data-platforms="all"><td>…and typecheck too</td><td><code>mm-harness check diff --profile full</code></td></tr>
216
+ <tr data-platforms="all"><td>Fix what is fixable, then validate</td><td><code>mm-harness check diff --fix</code></td></tr>
217
+ <tr data-platforms="all"><td>Write validation artifacts</td><td><code>mm-harness check diff --artifacts-dir artifacts/validation</code></td></tr>
218
+ </tbody>
219
+ </table>
220
+ </div>
221
+ <p class="step-why" style="font-size:.92rem">
222
+ <code>check</code> is bounded to the active git diff. It launches no app and runs no recipe.
223
+ </p>
224
+ </div>
225
+
226
+ <div data-filter-section>
227
+ <h2 id="agents">For agents and scripts</h2>
228
+ <div class="table-scroll" data-copy-cells>
229
+ <table>
230
+ <thead><tr><th>Flag / concept</th><th>What it does</th></tr></thead>
231
+ <tbody>
232
+ <tr data-platforms="all"><td><code>--json</code></td><td>Machine-readable output on every command. This is the agent contract.</td></tr>
233
+ <tr data-platforms="all"><td><code>--json-stream</code></td><td>Line-flushed JSONL progress plus a terminal event, on <code>run</code> and <code>launch</code>.</td></tr>
234
+ <tr data-platforms="all"><td><code>--heal off</code></td><td>Fail fast, preserve the repro. Nothing is repaired under you.</td></tr>
235
+ <tr data-platforms="all"><td><code>--heal infra-only</code></td><td>Heal transport, never wallet state. Default for <code>run</code> and <code>call</code>.</td></tr>
236
+ <tr data-platforms="all"><td><code>--heal auto</code></td><td>Auto-ensure the overlay and heal. Default for <code>launch</code>.</td></tr>
237
+ <tr data-platforms="all"><td><code>--adapter</code></td><td>Force the product when auto-detection is not what you want.</td></tr>
238
+ <tr data-platforms="all"><td><code>--target &lt;path&gt;</code></td><td>Operate on a checkout other than the current directory.</td></tr>
239
+ <tr data-platforms="all"><td><code>--library &lt;name=path&gt;</code></td><td>Add or override a recipe-library source. Repeatable.</td></tr>
240
+ </tbody>
241
+ </table>
242
+ </div>
243
+
244
+ <h3>Exit codes</h3>
245
+ <div class="table-scroll" data-copy-cells>
246
+ <table>
247
+ <thead><tr><th>Code</th><th>Meaning</th><th>Whose problem</th></tr></thead>
248
+ <tbody>
249
+ <tr data-platforms="all"><td><code>0</code></td><td>Success</td><td>—</td></tr>
250
+ <tr data-platforms="all"><td><code>1</code></td><td>Runtime / action failure</td><td>The thing under test. A real result.</td></tr>
251
+ <tr data-platforms="all"><td><code>2</code></td><td>Invalid CLI usage</td><td>Your command line.</td></tr>
252
+ <tr data-platforms="all"><td><code>3</code></td><td>Infrastructure failure</td><td>The environment — app or dev server.</td></tr>
253
+ <tr data-platforms="all"><td><code>4</code></td><td>Bounded recovery refusal</td><td>Healing hit its limit and stopped rather than thrashing.</td></tr>
254
+ <tr data-platforms="all"><td><code>5</code></td><td>Validation / trust failure</td><td>The recipe. Nothing executed.</td></tr>
255
+ </tbody>
256
+ </table>
257
+ </div>
258
+ <p class="step-why" style="font-size:.92rem">
259
+ The distinction that matters when triaging: <code>1</code> means it ran and failed;
260
+ <code>3</code> and <code>5</code> mean it never got to run.
261
+ </p>
262
+ </div>
263
+
264
+ <div data-filter-section>
265
+ <h2 id="setup">Setup and upkeep</h2>
266
+ <div class="table-scroll" data-copy-cells>
267
+ <table>
268
+ <thead><tr><th>Situation</th><th>Command</th></tr></thead>
269
+ <tbody>
270
+ <tr data-platforms="all"><td>Install or update</td><td><code>npm i -g @deeeed/metamask-harness@latest</code></td></tr>
271
+ <tr data-platforms="all"><td>Update in place</td><td><code>mm-harness update</code></td></tr>
272
+ <tr data-platforms="all"><td>Is there a newer version (no install)</td><td><code>mm-harness update --check</code></td></tr>
273
+ <tr data-platforms="all"><td>Tab completion for zsh / bash</td><td><code>mm-harness completions install</code></td></tr>
274
+ <tr data-platforms="all"><td>Silence the daily update nudge</td><td><code>MM_HARNESS_NO_UPDATE_CHECK=1</code></td></tr>
275
+ <tr data-platforms="all"><td>Point at a source checkout instead of the global install</td><td><code>MM_HARNESS_BIN=/path/to/checkout/bin/mm-harness</code></td></tr>
276
+ </tbody>
277
+ </table>
278
+ </div>
279
+ </div>
280
+
281
+ <p class="filter-empty" hidden>Nothing on this page applies to that platform.</p>
282
+
283
+ <hr class="sep">
284
+ <div class="note plain">
285
+ <span class="note-title">When this page and your terminal disagree</span>
286
+ <p>
287
+ Your terminal wins. The CLI ships fast, and every command carries its own help:
288
+ <code>mm-harness --help</code> for the map, <code>mm-harness &lt;command&gt; --help</code> for
289
+ flags and worked examples. Run <code>mm-harness update</code> first — most disagreements are a
290
+ stale global install.
291
+ </p>
292
+ </div>
293
+ </section>
294
+ </main>
295
+
296
+ <footer class="footer">
297
+ <div class="wrap-wide">
298
+ <p>Internal getting-started guide for the MetaMask agentic coding workflow. Not official MetaMask product documentation.</p>
299
+ <p>Verified against mm-harness 0.26+.</p>
300
+ </div>
301
+ </footer>
302
+
303
+ <script type="module" src="assets/progress.mjs"></script>
304
+ </body>
305
+ </html>