@deeeed/metamask-harness 0.34.2 → 0.34.4
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 +22 -0
- package/dist/adapters/mobile/source-freshness.js +51 -14
- package/dist/adapters.js +5 -2
- package/dist/recipe-security.js +1 -0
- package/library/actions/core/perps/_controller.mjs +75 -23
- package/library/actions/core/perps/read_account.mjs +6 -12
- package/library/actions/core/perps/read_snapshot.mjs +66 -0
- package/library/actions/extension/performance/_navigation-memory.mjs +372 -0
- package/library/actions/extension/performance/compare_idle_navigation_memory.mjs +18 -0
- package/library/actions/extension/performance/measure_detached_dom.mjs +18 -0
- package/library/actions/extension/performance/measure_navigation_memory.mjs +18 -0
- package/library/actions/mobile/app/network-control.mjs +24 -12
- package/library/manifests/core.action-manifest.json +55 -0
- package/library/manifests/extension.action-manifest.json +100 -0
- package/library/recipes/core/perps/snapshot.recipe.json +25 -0
- package/library/recipes/extension/performance/navigation-memory.recipe.json +175 -0
- package/package.json +1 -1
- package/scripts/site-contrast.mjs +66 -10
- package/site/architecture.html +22 -16
- package/site/assets/progress.mjs +47 -2
- package/site/assets/style.css +181 -1
- package/site/cheatsheet.html +14 -12
- package/site/how-it-works.html +693 -0
- package/site/index.html +133 -643
- package/site/perps.html +7 -6
- package/site/recipes.html +23 -17
- package/site/reviewers.html +7 -6
- package/site/tutorials/index.html +7 -6
- package/site/tutorials/v1.html +12 -11
- package/site/tutorials/v2.html +7 -6
- package/site/tutorials/v3.html +15 -11
- package/site/tutorials/v4.html +6 -5
- package/site/tutorials/v5.html +6 -5
- package/site/tutorials/v6.html +6 -5
- package/site/tutorials/v7.html +6 -5
package/site/index.html
CHANGED
|
@@ -3,81 +3,50 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
-
<title>
|
|
7
|
-
<meta name="description" content="
|
|
6
|
+
<title>Recipes — build with proof, not hope</title>
|
|
7
|
+
<meta name="description" content="A skill drives the change. The recipe proves it on a real MetaMask build as it is written, self-checked in the same context and kept as a regression guard.">
|
|
8
8
|
<link rel="stylesheet" href="assets/style.css">
|
|
9
9
|
</head>
|
|
10
|
-
<body
|
|
11
|
-
<a class="skip" href="#
|
|
10
|
+
<body>
|
|
11
|
+
<a class="skip" href="#prompt">Skip to the prompt</a>
|
|
12
|
+
|
|
13
|
+
<main class="lobby">
|
|
14
|
+
<div class="lobby-inner">
|
|
15
|
+
<span class="lobby-mark" aria-hidden="true"></span>
|
|
16
|
+
<span class="eyebrow">Proven as it's built</span>
|
|
17
|
+
|
|
18
|
+
<h1>Build agentically, with confidence.</h1>
|
|
19
|
+
<p class="lobby-lede">
|
|
20
|
+
A skill drives the change. The recipe proves it on a real MetaMask build as it is written —
|
|
21
|
+
self-checked in the same context, then kept as a regression guard.
|
|
22
|
+
</p>
|
|
23
|
+
<p class="lobby-sub">
|
|
24
|
+
Set up once, then work a real ticket.
|
|
25
|
+
</p>
|
|
12
26
|
|
|
13
|
-
<
|
|
14
|
-
<div class="wrap 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" aria-current="page">Start Here</a>
|
|
21
|
-
<a href="recipes.html">Recipes</a>
|
|
22
|
-
<a href="perps.html">Perps</a>
|
|
23
|
-
<a href="cheatsheet.html">Cheatsheet</a>
|
|
24
|
-
<a href="architecture.html">Architecture</a>
|
|
25
|
-
<a href="tutorials/index.html">Tutorials</a>
|
|
26
|
-
<a href="reviewers.html">For Reviewers</a>
|
|
27
|
-
</nav>
|
|
28
|
-
</div>
|
|
29
|
-
</header>
|
|
27
|
+
<section class="qs">
|
|
30
28
|
|
|
31
|
-
<div class="
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
<span class="progress-label">0/8 steps</span>
|
|
37
|
-
<button type="button" class="progress-reset">Reset</button>
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
|
|
41
|
-
<main>
|
|
42
|
-
<section class="wrap hero">
|
|
43
|
-
<span class="eyebrow">A proposed agentic workflow at MetaMask</span>
|
|
44
|
-
<h1>Drive the wallet. Prove what happened.</h1>
|
|
45
|
-
<p class="lede">
|
|
46
|
-
<code>mm-harness</code> launches a real MetaMask build — Extension, Mobile, or Core — drives it
|
|
47
|
-
through typed actions, and writes evidence a reviewer can check without taking your word for it.
|
|
48
|
-
Paste one prompt and let your agent do it, or walk the eight steps yourself.
|
|
49
|
-
</p>
|
|
50
|
-
<div class="hero-meta">
|
|
51
|
-
<span>requires mm-harness 0.33+</span>
|
|
52
|
-
<span>~20 minutes</span>
|
|
53
|
-
<span>progress saves in this browser</span>
|
|
54
|
-
</div>
|
|
55
|
-
<p style="margin-top:.9rem;opacity:.7;font-size:.9rem;max-width:60ch">
|
|
56
|
-
A proposal for how agents can code at MetaMask — offered for teams to try, not an official standard.
|
|
57
|
-
</p>
|
|
58
|
-
</section>
|
|
29
|
+
<div class="qs-step">
|
|
30
|
+
<h2 class="qs-title"><span class="qs-num" aria-hidden="true">1</span>Set up</h2>
|
|
31
|
+
<p class="qs-why">
|
|
32
|
+
One time per machine. Paste this into your agent inside a MetaMask checkout.
|
|
33
|
+
</p>
|
|
59
34
|
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<p>
|
|
64
|
-
Start your agent in or near a MetaMask checkout. This installs the harness, proves control of a
|
|
65
|
-
real build, runs a recipe, and re-runs it — end to end, without reading the rest of this page.
|
|
66
|
-
</p>
|
|
67
|
-
<div class="cmd cmd-hero"><pre><code>Task: set me up with the MetaMask recipe workflow and prove it works end to end.
|
|
68
|
-
Follow these steps in order. When a command fails, its message names the exact
|
|
69
|
-
next command — run that instead of improvising.
|
|
35
|
+
<div class="cmd cmd-hero" id="prompt"><pre><code>Task: set me up for recipe-backed work on MetaMask. Follow these steps in order.
|
|
36
|
+
When a command fails, its message names the exact next command — run that
|
|
37
|
+
instead of improvising.
|
|
70
38
|
|
|
71
39
|
1. Install the harness: `npm i -g @deeeed/metamask-harness@latest`, then
|
|
72
40
|
`mm-harness --version` to confirm it resolved.
|
|
73
41
|
2. Checkout: if I started you inside a MetaMask product checkout
|
|
74
42
|
(metamask-extension, metamask-mobile, or core), use it. If not, run
|
|
75
43
|
`mm-harness setup-base --dry-run` to show me the layout it would create,
|
|
76
|
-
and ask me before running it for real.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
44
|
+
and ask me before running it for real. Everything below runs from inside
|
|
45
|
+
the checkout.
|
|
46
|
+
3. Run `mm-harness doctor` and fix every finding by following its own
|
|
47
|
+
instructions until doctor passes. `mm-harness doctor --fix` repairs
|
|
48
|
+
harness-owned runtime state; it will not invent credentials or pick a
|
|
49
|
+
wallet fixture for me.
|
|
81
50
|
4. Run `mm-harness fixtures`. If no fixture exists, run
|
|
82
51
|
`mm-harness fixtures init --dev`; this creates a disposable public test
|
|
83
52
|
wallet that must never receive real funds.
|
|
@@ -95,594 +64,115 @@ next command — run that instead of improvising.
|
|
|
95
64
|
`--preflight-mode` is an internal adapter flag, not a public launch flag.
|
|
96
65
|
6. On Extension run `mm-harness fixtures set`. On Mobile include the same
|
|
97
66
|
`--device <UUID-or-serial>` used for launch. Wait for it to succeed.
|
|
98
|
-
7.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
<p>
|
|
139
|
-
<strong>Prevents regressions.</strong> The recipe outlives the change it was written for. Every
|
|
140
|
-
later change has to pass it too, so the same bug cannot quietly come back: a one-time check becomes
|
|
141
|
-
a permanent guard.
|
|
142
|
-
</p>
|
|
143
|
-
<p>
|
|
144
|
-
<strong>Trust.</strong> Proven, self-checked, and still proving — so review reads evidence instead
|
|
145
|
-
of extending credit, and every gate stays yours to steer.
|
|
146
|
-
</p>
|
|
147
|
-
</section>
|
|
148
|
-
|
|
149
|
-
<section class="wrap">
|
|
150
|
-
<h2 id="model">Two words</h2>
|
|
151
|
-
<p>
|
|
152
|
-
An <strong>action</strong> is one typed operation: unlock the wallet, press a button, read the
|
|
153
|
-
account state. A <strong>recipe</strong> is a JSON graph of actions. The steps below follow
|
|
154
|
-
<strong>discover → drive → prove</strong>, which is also the order you will work in from here on.
|
|
155
|
-
<code>mm-harness</code> implements the farmslot specification —
|
|
156
|
-
<a href="architecture.html#spec">see Architecture</a>.
|
|
157
|
-
</p>
|
|
158
|
-
|
|
159
|
-
<div class="doctrine">
|
|
160
|
-
<p>
|
|
161
|
-
<span class="k">You never guess capabilities — you discover them.</span>
|
|
162
|
-
<code>mm-harness actions</code> prints what this checkout can do, and that list is law. The tool
|
|
163
|
-
refuses an invented action rather than improvising one, which is why its output is worth
|
|
164
|
-
trusting.
|
|
165
|
-
</p>
|
|
166
|
-
</div>
|
|
167
|
-
</section>
|
|
168
|
-
|
|
169
|
-
<section class="wrap">
|
|
170
|
-
<h2 id="steps">Prefer to go step by step?</h2>
|
|
171
|
-
<p>Here is each piece on its own. Checkboxes persist in this browser, so you can close the tab and come back.</p>
|
|
172
|
-
|
|
173
|
-
<ol class="steps">
|
|
174
|
-
|
|
175
|
-
<li class="step" data-step="install">
|
|
176
|
-
<div class="step-head">
|
|
177
|
-
<input type="checkbox" class="step-check" id="c-install" aria-labelledby="t-install">
|
|
178
|
-
<h3 class="step-title" id="t-install">Get the CLI</h3>
|
|
179
|
-
</div>
|
|
180
|
-
<p class="step-why">Both paths end with <code>mm-harness</code> on your PATH.</p>
|
|
181
|
-
|
|
182
|
-
<div class="grid grid-2" style="margin:1.2rem 0">
|
|
183
|
-
<div class="path-card">
|
|
184
|
-
<div class="path-tag">Path A — from zero</div>
|
|
185
|
-
<h4 style="margin:0 0 .5rem">No checkout yet</h4>
|
|
186
|
-
<p style="font-size:.92rem;color:var(--text-dim)">
|
|
187
|
-
Install below, then <code>mm-harness setup-base</code> clones the MetaMask product repos
|
|
188
|
-
into one standard layout and runs each repo's own dependency install. Use
|
|
189
|
-
<code>--dry-run</code> first to see the layout it would create.
|
|
190
|
-
</p>
|
|
191
|
-
<p style="margin-bottom:0"><span class="badge live">available now</span></p>
|
|
192
|
-
</div>
|
|
193
|
-
<div class="path-card">
|
|
194
|
-
<div class="path-tag">Path B — you already have a checkout</div>
|
|
195
|
-
<h4 style="margin:0 0 .5rem">Install and cd in</h4>
|
|
196
|
-
<p style="font-size:.92rem;color:var(--text-dim)">
|
|
197
|
-
Install globally, then work from inside the checkout. The product, ports, and runtime paths
|
|
198
|
-
are detected from where you are standing; there is no config file to write.
|
|
199
|
-
</p>
|
|
200
|
-
<p style="margin-bottom:0"><span class="badge live">available now</span></p>
|
|
201
|
-
</div>
|
|
202
|
-
</div>
|
|
203
|
-
|
|
204
|
-
<div class="cmd"><pre><code><span class="p">$ </span>npm i -g @deeeed/metamask-harness@latest
|
|
205
|
-
<span class="p">$ </span>mm-harness --version</code></pre></div>
|
|
206
|
-
|
|
207
|
-
<div class="out-label">Expected</div>
|
|
208
|
-
<div class="out">0.33.x <span class="dim">— any 0.33 or newer</span></div>
|
|
209
|
-
|
|
210
|
-
<p class="step-why">Everything from here runs inside a product checkout:</p>
|
|
211
|
-
<div class="cmd"><pre><code><span class="p">$ </span>cd ~/dev/metamask/metamask-extension <span class="dim"># or metamask-mobile, or core</span></code></pre></div>
|
|
212
|
-
|
|
213
|
-
<details class="fail">
|
|
214
|
-
<summary>If it fails</summary>
|
|
215
|
-
<div class="fail-body">
|
|
216
|
-
<p>
|
|
217
|
-
<strong><code>mm-harness: command not found</code></strong> — your global npm bin is not on
|
|
218
|
-
PATH. <code>npm prefix -g</code> prints the global prefix; add its <code>bin</code>
|
|
219
|
-
directory to your shell profile.
|
|
220
|
-
</p>
|
|
221
|
-
<p>
|
|
222
|
-
<strong>Older than 0.33</strong> — a stale global install is the most common source of
|
|
223
|
-
"the docs don't match my terminal". Run <code>mm-harness update</code>, or
|
|
224
|
-
<code>update --check</code> to look without installing.
|
|
225
|
-
</p>
|
|
226
|
-
</div>
|
|
227
|
-
</details>
|
|
228
|
-
</li>
|
|
229
|
-
|
|
230
|
-
<li class="step" data-step="doctor">
|
|
231
|
-
<div class="step-head">
|
|
232
|
-
<input type="checkbox" class="step-check" id="c-doctor" aria-labelledby="t-doctor">
|
|
233
|
-
<h3 class="step-title" id="t-doctor">Run doctor — and learn to read the errors</h3>
|
|
234
|
-
</div>
|
|
235
|
-
<p class="step-why">
|
|
236
|
-
A read-only readiness check that launches nothing and names the exact command that fixes each
|
|
237
|
-
finding.
|
|
238
|
-
</p>
|
|
239
|
-
|
|
240
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness doctor</code></pre></div>
|
|
241
|
-
|
|
242
|
-
<div class="out-label">Expected — a checkout that needs one repair</div>
|
|
243
|
-
<div class="out"><span class="ok">pass</span> extension bridge present manifest=…/extension.action-manifest.json
|
|
244
|
-
harness: @deeeed/metamask-harness@0.33.x
|
|
245
|
-
runtime: decision=install (deps-missing) deps=missing webpack=down
|
|
246
|
-
Dependencies are not installed (no yarn install-state markers).
|
|
247
|
-
runtime-context: temp/recipe/runtime/agentic-runtime.json (<span class="bad">absent</span> — run mm-harness doctor --fix)
|
|
248
|
-
capture: <span class="ok">pass</span> (screenshots: capture-helper → cdp; video: capture-helper)
|
|
249
|
-
<span class="hint">Next: mm-harness launch --adapter extension --target '…'</span></div>
|
|
250
|
-
|
|
251
|
-
<div class="note">
|
|
252
|
-
<span class="note-title">The habit the toolchain is built around</span>
|
|
253
|
-
<p>
|
|
254
|
-
Every failure names one next action. Above, the finding tells you to run
|
|
255
|
-
<code>doctor --fix</code> and the <code>Next:</code> line says where to go once it passes.
|
|
256
|
-
Read the message and do what it says — that is also what lets an agent recover on its own
|
|
257
|
-
instead of guessing.
|
|
258
|
-
</p>
|
|
259
|
-
</div>
|
|
260
|
-
|
|
261
|
-
<p class="step-why">Do what it said:</p>
|
|
262
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness doctor --fix</code></pre></div>
|
|
263
|
-
|
|
264
|
-
<div class="out-label">Expected — the finding is gone</div>
|
|
265
|
-
<div class="out"><span class="ok">pass</span> extension bridge present ready=true <span class="ok">fixed=[runtime-context]</span> failed=[]</div>
|
|
266
|
-
|
|
267
|
-
<p class="step-why">
|
|
268
|
-
<code>--fix</code> repairs runtime state the harness owns. It will not launch the app, invent
|
|
269
|
-
credentials, or pick a wallet fixture; those are your decisions, so it stops and asks.
|
|
270
|
-
</p>
|
|
271
|
-
|
|
272
|
-
<details class="fail">
|
|
273
|
-
<summary>If it fails</summary>
|
|
274
|
-
<div class="fail-body">
|
|
275
|
-
<p>
|
|
276
|
-
<strong><code>deps=missing</code></strong> — run <code>yarn install</code> as usual for
|
|
277
|
-
that repo. The harness does not manage your product repo's dependencies.
|
|
278
|
-
</p>
|
|
279
|
-
<p>
|
|
280
|
-
<strong>A finding you do not understand</strong> — <code>mm-harness doctor --json</code>
|
|
281
|
-
carries the same findings with structured detail, and is the form to paste to an agent or a
|
|
282
|
-
bug report.
|
|
283
|
-
</p>
|
|
284
|
-
<p>
|
|
285
|
-
<strong>Still failing after <code>--fix</code></strong> — <code>fixed=[…] failed=[…]</code>
|
|
286
|
-
separates the two. Anything in <code>failed</code> needs a human decision; the finding says
|
|
287
|
-
which.
|
|
288
|
-
</p>
|
|
289
|
-
</div>
|
|
290
|
-
</details>
|
|
291
|
-
</li>
|
|
292
|
-
|
|
293
|
-
<li class="step" data-step="launch">
|
|
294
|
-
<div class="step-head">
|
|
295
|
-
<input type="checkbox" class="step-check" id="c-launch" aria-labelledby="t-launch">
|
|
296
|
-
<h3 class="step-title" id="t-launch">Launch the app under harness control</h3>
|
|
297
|
-
</div>
|
|
298
|
-
<p class="step-why">
|
|
299
|
-
Starts the app and its dev server, installing the runtime overlay first if missing. Platform is
|
|
300
|
-
auto-detected. On iOS, pin one simulator UUID through provisioning and launch so duplicate device
|
|
301
|
-
names cannot select different simulators.
|
|
302
|
-
</p>
|
|
303
|
-
|
|
304
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness launch --verify <span class="dim"># extension — fullscreen by default</span>
|
|
305
|
-
<span class="p">$ </span>xcrun simctl list devices available <span class="dim"># choose one iPhone UUID</span>
|
|
306
|
-
<span class="p">$ </span>mm-harness provision runway ios --device '<UUID>' --force
|
|
307
|
-
<span class="p">$ </span>xcrun simctl get_app_container '<UUID>' io.metamask.MetaMask app
|
|
308
|
-
<span class="p">$ </span>mm-harness launch ios --device '<UUID>' --verify
|
|
309
|
-
<span class="p">$ </span>mm-harness launch android --verify</code></pre></div>
|
|
310
|
-
|
|
311
|
-
<p class="step-why">
|
|
312
|
-
Quick relaunch is the default and reuses a healthy runtime. <code>--build</code> is the escape
|
|
313
|
-
hatch that always clean-builds; reach for it only when native or bundler output changed.
|
|
314
|
-
</p>
|
|
315
|
-
|
|
316
|
-
<div class="out-label">Core is headless — and says so</div>
|
|
317
|
-
<div class="out"><span class="bad">✗</span> mm-harness launch: core is headless; there is nothing to launch.
|
|
318
|
-
<span class="hint">Next: mm-harness verify</span></div>
|
|
319
|
-
<p class="step-why">
|
|
320
|
-
In <code>core</code> there is no UI to launch, so you get the equivalent step instead of a
|
|
321
|
-
silent failure. Run <code>mm-harness verify</code> and continue.
|
|
322
|
-
</p>
|
|
323
|
-
|
|
324
|
-
<details class="fail">
|
|
325
|
-
<summary>If it fails</summary>
|
|
326
|
-
<div class="fail-body">
|
|
327
|
-
<p>
|
|
328
|
-
<strong>Mobile: more than one device</strong> — the harness lists what it found rather than
|
|
329
|
-
guessing. Re-run with <code>--device <udid|serial></code>. Prefer the iOS UUID over a name,
|
|
330
|
-
because Xcode can contain several simulators with the same display name.
|
|
331
|
-
</p>
|
|
332
|
-
<p>
|
|
333
|
-
<strong>iOS app missing after provisioning</strong> — repeat the provision command with
|
|
334
|
-
<code>--force</code> and the same UUID. Do not use <code>--preflight-mode</code>; it is an
|
|
335
|
-
internal adapter flag, not a public <code>mm-harness launch</code> option.
|
|
336
|
-
</p>
|
|
337
|
-
<p>
|
|
338
|
-
<strong>Stuck</strong> — <code>mm-harness logs</code> tails the dev server and app logs;
|
|
339
|
-
<code>mm-harness status</code> shows the adapter, devices, and next command.
|
|
340
|
-
</p>
|
|
341
|
-
<p>
|
|
342
|
-
<strong>Clean slate</strong> — <code>mm-harness stop</code> stops only what this checkout
|
|
343
|
-
owns, so parallel checkouts are untouched. Stopping nothing is success.
|
|
344
|
-
</p>
|
|
345
|
-
</div>
|
|
346
|
-
</details>
|
|
347
|
-
</li>
|
|
348
|
-
|
|
349
|
-
<li class="step" data-step="actions">
|
|
350
|
-
<div class="step-head">
|
|
351
|
-
<input type="checkbox" class="step-check" id="c-actions" aria-labelledby="t-actions">
|
|
352
|
-
<h3 class="step-title" id="t-actions">Discover what this checkout can do</h3>
|
|
353
|
-
</div>
|
|
354
|
-
<p class="step-why">
|
|
355
|
-
Prints every typed operation available here, with its fields. The set differs per product:
|
|
356
|
-
Mobile has UI actions, Core is headless and has none.
|
|
357
|
-
</p>
|
|
358
|
-
|
|
359
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness actions --categories</code></pre></div>
|
|
360
|
-
|
|
361
|
-
<div class="out-label">Expected — a mobile checkout</div>
|
|
362
|
-
<div class="out">analytics (4)
|
|
363
|
-
assertion (4)
|
|
364
|
-
control (4)
|
|
365
|
-
evidence (2)
|
|
366
|
-
perps (11)
|
|
367
|
-
runtime (4)
|
|
368
|
-
ui (7)
|
|
369
|
-
utility (1)
|
|
370
|
-
wallet (6)</div>
|
|
371
|
-
|
|
372
|
-
<p class="step-why">Then look inside a category, search, or inspect one action's fields:</p>
|
|
373
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness actions --category ui
|
|
374
|
-
<span class="p">$ </span>mm-harness actions positions
|
|
375
|
-
<span class="p">$ </span>mm-harness actions --action read_state</code></pre></div>
|
|
376
|
-
|
|
377
|
-
<div class="doctrine">
|
|
378
|
-
<p>
|
|
379
|
-
<span class="k">The discovered list is law.</span> It is the capability boundary, not a
|
|
380
|
-
subset of some larger API. Call something not on it and the harness refuses, pointing you back
|
|
381
|
-
at discovery:
|
|
67
|
+
7. Install the skills — they are how the work actually gets driven. The
|
|
68
|
+
installer reads from LOCAL CLONES, so clone the sources first and add both
|
|
69
|
+
exports to my shell rc:
|
|
70
|
+
`git clone https://github.com/MetaMask/skills.git ~/dev/metamask/skills`
|
|
71
|
+
`export METAMASK_SKILLS_DIR=~/dev/metamask/skills`
|
|
72
|
+
Then the internal overlay, which needs access to the Consensys org:
|
|
73
|
+
`git clone git@github.com:Consensys/skills.git ~/dev/Consensys/skills`
|
|
74
|
+
`export CONSENSYS_SKILLS_DIR=~/dev/Consensys/skills`
|
|
75
|
+
If that clone fails, tell me — I may not have access, and the next step
|
|
76
|
+
depends on it. Then, from inside the checkout:
|
|
77
|
+
`yarn metamask-skills list --maturity experimental` everything installable
|
|
78
|
+
`yarn skills` installs the stable set
|
|
79
|
+
`yarn skills` runs `metamask-skills sync` and is already wired in
|
|
80
|
+
metamask-extension, metamask-mobile, and core. Use `--maturity experimental`
|
|
81
|
+
when listing: the default only prints stable skills, so the recipe skills
|
|
82
|
+
below do not appear without it.
|
|
83
|
+
8. Add the skills that drive recipe-backed work:
|
|
84
|
+
`yarn skills --include agentic/recipe-cook,agentic/recipe-quality,agentic/recipe-pr-qa-review --save`
|
|
85
|
+
They install as `mms-recipe-cook`, `mms-recipe-quality`, and
|
|
86
|
+
`mms-recipe-pr-qa-review`. They come from the `Consensys/skills` clone in
|
|
87
|
+
step 7 and are marked experimental, which is why the explicit `--include`
|
|
88
|
+
is required. If `yarn metamask-skills describe agentic/recipe-cook` cannot
|
|
89
|
+
find it, check `CONSENSYS_SKILLS_DIR` points at that clone, then stop and
|
|
90
|
+
tell me. Do not substitute a different skill.
|
|
91
|
+
9. Run `mm-harness actions`. That list is the ONLY set of capabilities you may
|
|
92
|
+
use, now and in every later session — never invent an action or a flag. Then
|
|
93
|
+
stop and tell me setup is done.
|
|
94
|
+
|
|
95
|
+
Not optional, from here on: evidence comes only from executed actions — never
|
|
96
|
+
fabricate a result or edit state to manufacture one. If the harness reports a
|
|
97
|
+
capability as unsupported, stop and tell me rather than working around it. If a
|
|
98
|
+
step fails twice after following its error's instructions, stop and show me the
|
|
99
|
+
exact error.</code></pre></div>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<div class="qs-step">
|
|
103
|
+
<h2 class="qs-title"><span class="qs-num" aria-hidden="true">2</span>Do real work</h2>
|
|
104
|
+
<p class="qs-why">
|
|
105
|
+
Pick what you are doing. Each one runs the skill that owns that flow, and leaves a
|
|
106
|
+
rerunnable recipe behind as the proof.
|
|
382
107
|
</p>
|
|
383
|
-
</div>
|
|
384
|
-
|
|
385
|
-
<div class="out"><span class="bad">✗</span> call: unknown action "totally_made_up" for the extension adapter.
|
|
386
|
-
<span class="hint">Next: mm-harness actions --adapter extension --json</span></div>
|
|
387
|
-
|
|
388
|
-
<p class="step-why">
|
|
389
|
-
That refusal is why the evidence is worth reading: a tool that invents an action when asked for
|
|
390
|
-
something impossible would also produce a plausible-looking result, and you would have no way to
|
|
391
|
-
tell. Add <code>--json</code> when feeding this to an agent.
|
|
392
|
-
</p>
|
|
393
|
-
|
|
394
|
-
<details class="fail">
|
|
395
|
-
<summary>If it fails</summary>
|
|
396
|
-
<div class="fail-body">
|
|
397
|
-
<p>
|
|
398
|
-
<strong>Fewer actions than expected</strong> — you are seeing only the bundled set. Team
|
|
399
|
-
libraries add domain actions and must be declared: <a href="tutorials/v3.html">V3</a>.
|
|
400
|
-
</p>
|
|
401
|
-
<p>
|
|
402
|
-
<strong>Wrong product detected</strong> — pass <code>--adapter mobile|extension|core</code>
|
|
403
|
-
explicitly, and check you are inside the checkout you meant.
|
|
404
|
-
</p>
|
|
405
|
-
</div>
|
|
406
|
-
</details>
|
|
407
|
-
</li>
|
|
408
|
-
|
|
409
|
-
<li class="step" data-step="call-read">
|
|
410
|
-
<div class="step-head">
|
|
411
|
-
<input type="checkbox" class="step-check" id="c-call-read" aria-labelledby="t-call-read">
|
|
412
|
-
<h3 class="step-title" id="t-call-read">Drive it: read product state</h3>
|
|
413
|
-
</div>
|
|
414
|
-
<p class="step-why">
|
|
415
|
-
<code>call</code> runs one action as a one-node recipe through the real engine — same execution
|
|
416
|
-
path, trace, and evidence as a full run. Start with a read; reads cannot break anything.
|
|
417
|
-
</p>
|
|
418
|
-
|
|
419
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness call read_state</code></pre></div>
|
|
420
|
-
|
|
421
|
-
<div class="note blue">
|
|
422
|
-
<span class="note-title">Core branch</span>
|
|
423
|
-
<p>
|
|
424
|
-
Core has no wallet UI. Exercise its live controller boundary instead:
|
|
425
|
-
<code>mm-harness call read_positions mode=all</code>.
|
|
426
|
-
</p>
|
|
427
|
-
</div>
|
|
428
|
-
|
|
429
|
-
<p class="step-why">
|
|
430
|
-
Short names resolve when unambiguous: <code>read_state</code> finds
|
|
431
|
-
<code>metamask.wallet.read_state</code>. An ambiguous one stops and lists the candidates.
|
|
432
|
-
</p>
|
|
433
|
-
|
|
434
|
-
<div class="out-label">Expected — shape of the result</div>
|
|
435
|
-
<div class="out">call read_state: <span class="ok">pass</span>
|
|
436
|
-
Result:
|
|
437
|
-
{
|
|
438
|
-
"action": "metamask.wallet.read_state",
|
|
439
|
-
"state": {
|
|
440
|
-
"selectedAccount": { "name": "Account 1", "address": "0x…" },
|
|
441
|
-
"completedOnboarding": true
|
|
442
|
-
},
|
|
443
|
-
"redacted": true
|
|
444
|
-
}</div>
|
|
445
|
-
|
|
446
|
-
<p class="step-why">
|
|
447
|
-
Note <code>"redacted": true</code> — wallet state passes through redaction before reaching an
|
|
448
|
-
artifact, because these bundles get attached to pull requests.
|
|
449
|
-
</p>
|
|
450
108
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
<
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
<
|
|
459
|
-
<
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
109
|
+
<div class="tabs">
|
|
110
|
+
<div class="tablist" role="tablist" aria-label="Choose what to do">
|
|
111
|
+
<button type="button" role="tab" id="tab-review" class="tab" aria-controls="panel-review" aria-selected="true" tabindex="0">Review a PR</button>
|
|
112
|
+
<button type="button" role="tab" id="tab-fix" class="tab" aria-controls="panel-fix" aria-selected="false" tabindex="-1">Fix a bug</button>
|
|
113
|
+
<button type="button" role="tab" id="tab-build" class="tab" aria-controls="panel-build" aria-selected="false" tabindex="-1">Build a feature</button>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<div class="qs-panel" role="tabpanel" id="panel-review" aria-labelledby="tab-review" tabindex="0">
|
|
117
|
+
<p class="qs-panel-why">
|
|
118
|
+
<code>mms-recipe-pr-qa-review</code> — read-only. It freezes the acceptance criteria
|
|
119
|
+
before it touches the runtime, validates each one on a real build, and returns a report.
|
|
120
|
+
It never edits product code and never posts to GitHub. The PR must be in the same
|
|
121
|
+
product as your checkout.
|
|
122
|
+
</p>
|
|
123
|
+
<div class="cmd"><pre><code>/mms-recipe-pr-qa-review https://github.com/MetaMask/metamask-mobile/pull/<number>
|
|
124
|
+
|
|
125
|
+
Extract the acceptance criteria from the PR yourself and freeze them before any
|
|
126
|
+
runtime work. Validate each one against the running build, then give me the
|
|
127
|
+
per-AC verdict table, the overall verdict, and the artifact paths. Do not post
|
|
128
|
+
anything on the PR.</code></pre></div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div class="qs-panel" role="tabpanel" id="panel-fix" aria-labelledby="tab-fix" tabindex="0" hidden>
|
|
132
|
+
<p class="qs-panel-why">
|
|
133
|
+
<code>mms-recipe-cook</code>, classified as <code>fix-bug</code>. It lists the
|
|
134
|
+
compatible checklist templates and stops for your pick, then works on a local task
|
|
135
|
+
branch. No product edits until the bug is proven to reproduce.
|
|
136
|
+
</p>
|
|
137
|
+
<div class="cmd"><pre><code>/mms-recipe-cook
|
|
138
|
+
|
|
139
|
+
Fix this in the checkout I started you in — treat it as fix-bug:
|
|
140
|
+
<paste the ticket, or the broken behaviour and how to reproduce it>
|
|
141
|
+
|
|
142
|
+
Reproduce it on the real build first and keep that failing run as the baseline.
|
|
143
|
+
Then fix it and re-run the same recipe until it passes. Show me the recipe
|
|
144
|
+
status, the per-node results, and the artifact paths.</code></pre></div>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<div class="qs-panel" role="tabpanel" id="panel-build" aria-labelledby="tab-build" tabindex="0" hidden>
|
|
148
|
+
<p class="qs-panel-why">
|
|
149
|
+
<code>mms-recipe-cook</code>, classified as <code>dev</code>. Same flow: it lists the
|
|
150
|
+
compatible templates, stops for your pick, and keeps the diff uncommitted until you
|
|
151
|
+
ask it to package the PR.
|
|
152
|
+
</p>
|
|
153
|
+
<div class="cmd"><pre><code>/mms-recipe-cook
|
|
154
|
+
|
|
155
|
+
Build this in the checkout I started you in — treat it as dev:
|
|
156
|
+
<paste the ticket, or the change you want>
|
|
157
|
+
|
|
158
|
+
Plan the proof before you edit anything, implement it, then prove it with a
|
|
159
|
+
recipe that drives the real build. Show me the recipe status, the per-node
|
|
160
|
+
results, and the artifact paths.</code></pre></div>
|
|
161
|
+
</div>
|
|
466
162
|
</div>
|
|
467
|
-
</details>
|
|
468
|
-
</li>
|
|
469
|
-
|
|
470
|
-
<li class="step" data-step="call-ui">
|
|
471
|
-
<div class="step-head">
|
|
472
|
-
<input type="checkbox" class="step-check" id="c-call-ui" aria-labelledby="t-call-ui">
|
|
473
|
-
<h3 class="step-title" id="t-call-ui">Drive it again: UI or headless Core</h3>
|
|
474
|
-
</div>
|
|
475
|
-
<p class="step-why">Keep the app visible for this one.</p>
|
|
476
|
-
|
|
477
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness call navigate page=perps</code></pre></div>
|
|
478
|
-
|
|
479
|
-
<div class="note blue">
|
|
480
|
-
<span class="note-title">Core branch</span>
|
|
481
|
-
<p>
|
|
482
|
-
Prove a second headless action instead:
|
|
483
|
-
<code>mm-harness call command cmd="echo core-ready"</code>.
|
|
484
|
-
</p>
|
|
485
|
-
</div>
|
|
486
|
-
|
|
487
|
-
<p class="step-why">
|
|
488
|
-
Fields are passed as <code>key=value</code>, or <code>--arg k=v</code> for the same effect.
|
|
489
|
-
</p>
|
|
490
|
-
|
|
491
|
-
<div class="note blue">
|
|
492
|
-
<span class="note-title">Semantic intent, not coordinates</span>
|
|
493
|
-
<p>
|
|
494
|
-
You asked for a <em>page</em>, not a pixel or a route. The adapter owns the mapping and
|
|
495
|
-
verifies where it landed, so a drifted route fails loudly instead of quietly doing nothing —
|
|
496
|
-
which is why these actions survive redesigns.
|
|
497
|
-
<code>mm-harness actions --action navigate</code> lists accepted values.
|
|
498
|
-
</p>
|
|
499
|
-
</div>
|
|
500
|
-
|
|
501
|
-
<p class="step-why">Others worth trying, if your adapter lists them:</p>
|
|
502
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness call press text="Account 1"
|
|
503
|
-
<span class="p">$ </span>mm-harness call screenshot path=proof.png</code></pre></div>
|
|
504
|
-
|
|
505
|
-
<details class="fail">
|
|
506
|
-
<summary>If it fails</summary>
|
|
507
|
-
<div class="fail-body">
|
|
508
|
-
<p>
|
|
509
|
-
<strong>Target not found</strong> — the element is not on screen. Actions do not hunt
|
|
510
|
-
blindly; use <code>wait_for</code> when something needs to mount first.
|
|
511
|
-
</p>
|
|
512
|
-
<p>
|
|
513
|
-
<strong>Core has no UI actions</strong> — correct, it is headless. Try
|
|
514
|
-
<code>mm-harness call command cmd="echo hello"</code> there instead.
|
|
515
|
-
</p>
|
|
516
|
-
</div>
|
|
517
|
-
</details>
|
|
518
|
-
</li>
|
|
519
|
-
|
|
520
|
-
<li class="step" data-step="run">
|
|
521
|
-
<div class="step-head">
|
|
522
|
-
<input type="checkbox" class="step-check" id="c-run" aria-labelledby="t-run">
|
|
523
|
-
<h3 class="step-title" id="t-run">Prove it: run your first recipe</h3>
|
|
524
163
|
</div>
|
|
525
|
-
<p class="step-why">
|
|
526
|
-
Everything so far was driving by hand. A recipe composes the same operations into a graph that
|
|
527
|
-
runs identically every time and records what happened. Start with what ships:
|
|
528
|
-
</p>
|
|
529
164
|
|
|
530
|
-
|
|
165
|
+
</section>
|
|
531
166
|
|
|
532
|
-
|
|
533
|
-
<
|
|
534
|
-
Inspect: mm-harness run <recipe> --describe
|
|
535
|
-
perps.smoke [metamask] variant=extension — Non-mutating Perps domain smoke…
|
|
536
|
-
runner.smoke [metamask] variant=extension — Proves the runner executes manifest-declared actions…
|
|
537
|
-
wallet.smoke [metamask] variant=extension — Fixture-backed proof that the wallet is reachable, unlocked…</div>
|
|
538
|
-
|
|
539
|
-
<p class="step-why">
|
|
540
|
-
Read one first. <code>--describe</code> shows its parameters and every action it composes:
|
|
541
|
-
</p>
|
|
542
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness run wallet.smoke --describe
|
|
543
|
-
<span class="p">$ </span>mm-harness run wallet.smoke --plan</code></pre></div>
|
|
544
|
-
|
|
545
|
-
<p class="step-why">
|
|
546
|
-
<code>--plan</code> validates and prints the execution plan while touching nothing, exiting 5 if
|
|
547
|
-
the recipe is invalid. Cheap check before the expensive one.
|
|
548
|
-
</p>
|
|
549
|
-
|
|
550
|
-
<p class="step-why">Now for real, with the evidence somewhere you chose:</p>
|
|
551
|
-
<div class="cmd"><pre><code><span class="p">$ </span>mm-harness run wallet.smoke --artifacts-dir ./first-recipe-artifacts</code></pre></div>
|
|
552
|
-
|
|
553
|
-
<div class="out-label">Expected</div>
|
|
554
|
-
<div class="out"><span class="ok">PASS</span> recipe run [extension]
|
|
555
|
-
summary:
|
|
556
|
-
<span class="ok">PASS</span> status (app.status, 9ms): platform=extension
|
|
557
|
-
<span class="ok">PASS</span> fixture (metamask.wallet.fixture_status, 17ms): path=temp/recipe/runtime/wallet-fixture.json
|
|
558
|
-
<span class="ok">PASS</span> unlock (metamask.wallet.ensure_unlocked, 100ms): proof=extension-unlocked-state
|
|
559
|
-
<span class="ok">PASS</span> state (metamask.wallet.read_state, 94ms): proof=extension-wallet-state
|
|
560
|
-
<span class="ok">PASS</span> screenshot (ui.screenshot, 6.0s): path=screenshots/wallet-smoke.png
|
|
561
|
-
<span class="ok">PASS</span> done (end, 0ms)
|
|
562
|
-
artifacts (6):
|
|
563
|
-
Human run report: ./first-recipe-artifacts/report.md
|
|
564
|
-
Run summary: ./first-recipe-artifacts/summary.json
|
|
565
|
-
Execution trace: ./first-recipe-artifacts/trace.json
|
|
566
|
-
Executed recipe: ./first-recipe-artifacts/recipe.json
|
|
567
|
-
<span class="dim">…</span></div>
|
|
568
|
-
|
|
569
|
-
<div class="note">
|
|
570
|
-
<span class="note-title">Wallet fixtures</span>
|
|
571
|
-
<p>
|
|
572
|
-
Recipes needing a signed-in wallet read one canonical fixture per checkout; the password comes
|
|
573
|
-
<em>from</em> the fixture and is never typed. On a missing fixture,
|
|
574
|
-
<code>mm-harness fixtures</code> shows its status and the safe next command.
|
|
575
|
-
<code>fixtures init --dev</code> creates a disposable public test wallet that must never hold
|
|
576
|
-
real funds.
|
|
577
|
-
</p>
|
|
578
|
-
</div>
|
|
579
|
-
|
|
580
|
-
<details class="fail">
|
|
581
|
-
<summary>If it fails</summary>
|
|
582
|
-
<div class="fail-body">
|
|
583
|
-
<p>
|
|
584
|
-
<strong>Exit 5</strong> — validation or trust failure. The recipe is the problem, not your
|
|
585
|
-
environment; nothing executed. The message names the invalid part.
|
|
586
|
-
</p>
|
|
587
|
-
<p>
|
|
588
|
-
<strong>Exit 1</strong> — it ran and an action failed. A real result, not a tooling
|
|
589
|
-
problem: find the first node in <code>trace.json</code> with <code>"ok": false</code>.
|
|
590
|
-
</p>
|
|
591
|
-
<p>
|
|
592
|
-
<strong>Exit 3</strong> — infrastructure, not your recipe: the app or dev server fell over.
|
|
593
|
-
Try <code>mm-harness doctor</code> then <code>mm-harness logs</code>.
|
|
594
|
-
</p>
|
|
595
|
-
<p>
|
|
596
|
-
<strong>Lost track</strong> — <code>mm-harness last</code> prints the last significant
|
|
597
|
-
command with its verdict and evidence paths.
|
|
598
|
-
</p>
|
|
599
|
-
</div>
|
|
600
|
-
</details>
|
|
601
|
-
</li>
|
|
602
|
-
|
|
603
|
-
<li class="step" data-step="evidence">
|
|
604
|
-
<div class="step-head">
|
|
605
|
-
<input type="checkbox" class="step-check" id="c-evidence" aria-labelledby="t-evidence">
|
|
606
|
-
<h3 class="step-title" id="t-evidence">Open the evidence bundle</h3>
|
|
607
|
-
</div>
|
|
608
|
-
<p class="step-why">The run left a directory behind. This is the part that beats clicking through by hand.</p>
|
|
609
|
-
|
|
610
|
-
<div class="cmd"><pre><code><span class="p">$ </span>ls first-recipe-artifacts
|
|
611
|
-
<span class="p">$ </span>cat first-recipe-artifacts/summary.json
|
|
612
|
-
<span class="p">$ </span>open first-recipe-artifacts/screenshots</code></pre></div>
|
|
613
|
-
|
|
614
|
-
<div class="table-scroll">
|
|
615
|
-
<table>
|
|
616
|
-
<thead><tr><th>File</th><th>What it answers</th></tr></thead>
|
|
617
|
-
<tbody>
|
|
618
|
-
<tr><td><code>summary.json</code></td><td>Did it pass? How many nodes, how long, which libraries were in play. The verdict.</td></tr>
|
|
619
|
-
<tr><td><code>trace.json</code></td><td>What happened at every step: per-node verdict, timing, inputs, outputs. Counts come from here.</td></tr>
|
|
620
|
-
<tr><td><code>recipe.json</code></td><td>The graph that actually executed, including each node's stated intent.</td></tr>
|
|
621
|
-
<tr><td><code>report.md</code></td><td>The same story in one readable page — the thing to skim first.</td></tr>
|
|
622
|
-
<tr><td><code>screenshots/</code></td><td>Visual evidence captured during the run.</td></tr>
|
|
623
|
-
<tr><td><code>diagnostics.json</code></td><td>Warnings and errors the app emitted, kept deliberately separate from the verdict.</td></tr>
|
|
624
|
-
</tbody>
|
|
625
|
-
</table>
|
|
626
|
-
</div>
|
|
627
|
-
|
|
628
|
-
<p class="step-why">
|
|
629
|
-
Read them in that order: <code>report.md</code>, then <code>summary.json</code> for the verdict,
|
|
630
|
-
then <code>trace.json</code> when you want to know why. Cite numbers from
|
|
631
|
-
<code>trace.json</code>, never from prose written around it.
|
|
632
|
-
</p>
|
|
633
|
-
|
|
634
|
-
<div class="btn-row" style="margin-top:1.2rem">
|
|
635
|
-
<a class="btn btn-primary" href="reviewers.html">Read a bundle line by line →</a>
|
|
636
|
-
</div>
|
|
637
|
-
|
|
638
|
-
<details class="fail">
|
|
639
|
-
<summary>If it fails</summary>
|
|
640
|
-
<div class="fail-body">
|
|
641
|
-
<p>
|
|
642
|
-
<strong>Cannot find the directory</strong> — without <code>--artifacts-dir</code> it goes
|
|
643
|
-
to a checkout-local run directory. <code>mm-harness last</code> prints the path.
|
|
644
|
-
</p>
|
|
645
|
-
<p>
|
|
646
|
-
<strong>No screenshots</strong> — capture differs per platform;
|
|
647
|
-
<code>mm-harness doctor</code> reports it on a <code>capture:</code> line. A degraded
|
|
648
|
-
fallback still succeeds and records that it degraded in the artifact metadata.
|
|
649
|
-
</p>
|
|
650
|
-
</div>
|
|
651
|
-
</details>
|
|
652
|
-
</li>
|
|
653
|
-
|
|
654
|
-
</ol>
|
|
655
|
-
</section>
|
|
656
|
-
|
|
657
|
-
<section class="wrap">
|
|
658
|
-
<hr class="sep">
|
|
659
|
-
<h2>Next</h2>
|
|
660
|
-
<div class="grid grid-3">
|
|
661
|
-
<div class="card">
|
|
662
|
-
<h3>What a recipe is</h3>
|
|
663
|
-
<p>The graph, the intents, the assertions, and the test of whether yours is worth keeping.</p>
|
|
664
|
-
<p><a href="recipes.html">Recipes →</a></p>
|
|
167
|
+
<div class="lobby-cta">
|
|
168
|
+
<a class="btn btn-primary" href="how-it-works.html">How it works →</a>
|
|
665
169
|
</div>
|
|
666
|
-
<div class="card">
|
|
667
|
-
<h3>Your team's library</h3>
|
|
668
|
-
<p>Install the skills, declare your library, prove discovery sees it.</p>
|
|
669
|
-
<p><a href="tutorials/v3.html">Tutorial V3 →</a></p>
|
|
670
|
-
</div>
|
|
671
|
-
<div class="card">
|
|
672
|
-
<h3>Reviewing someone's proof</h3>
|
|
673
|
-
<p>A real bundle annotated, including a degraded capture that stayed honest about it.</p>
|
|
674
|
-
<p><a href="reviewers.html">For reviewers →</a></p>
|
|
675
|
-
</div>
|
|
676
|
-
</div>
|
|
677
|
-
</section>
|
|
678
|
-
</main>
|
|
679
170
|
|
|
680
|
-
<
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
<p>Verified against mm-harness 0.33+. If a command here disagrees with your terminal, your terminal is right: run <code>mm-harness update</code>, then trust <code>--help</code>.</p>
|
|
171
|
+
<p class="lobby-fine">
|
|
172
|
+
A proposal for how agents can code at MetaMask — offered for teams to try, not an official standard.
|
|
173
|
+
</p>
|
|
684
174
|
</div>
|
|
685
|
-
</
|
|
175
|
+
</main>
|
|
686
176
|
|
|
687
177
|
<script type="module" src="assets/progress.mjs"></script>
|
|
688
178
|
</body>
|