@deeeed/metamask-harness 0.17.5 → 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 +872 -0
- package/README.md +94 -140
- package/adapters/extension/console-tail.mjs +55 -24
- package/adapters/extension/ensure-browser.sh +6 -1
- package/adapters/extension/inject.mjs +6 -9
- package/adapters/extension/launch-browser.cjs +7 -1
- package/adapters/extension/launch-webpack.cjs +83 -0
- package/adapters/extension/launch.sh +8 -11
- package/adapters/extension/lib/chrome-args.cjs +8 -1
- package/adapters/extension/lib/macos-focus.cjs +32 -0
- package/adapters/extension/live.sh +12 -21
- package/adapters/extension/reattach.sh +1 -0
- package/adapters/extension/seed-fixture.sh +4 -12
- package/adapters/extension/sidepanel-toggle.sh +4 -1
- package/adapters/extension/stamp-runtime-title.cjs +58 -0
- package/adapters/extension/start-watch.sh +17 -4
- package/adapters/extension/stop-viewers.sh +1 -1
- package/adapters/extension/sync-webpack-dist.cjs +107 -0
- package/adapters/extension/verify.sh +1 -1
- package/adapters/manifest.json +53 -37
- package/adapters/mobile/bridge-runtime/cdp-bridge.cjs +16 -0
- package/adapters/mobile/bridge-runtime/console-forwarder.cjs +1 -1
- package/adapters/mobile/bridge-runtime/lib/match-bridge-target.cjs +3 -1
- package/adapters/mobile/bridge-runtime/lib/target-discovery.cjs +2 -3
- package/adapters/mobile/cleanup.sh +16 -176
- package/adapters/mobile/inject.sh +90 -671
- package/adapters/mobile/launch-console-forwarder.cjs +39 -0
- package/adapters/mobile/open-device.sh +45 -7
- package/adapters/mobile/start-console-forwarder.sh +70 -0
- package/adapters/mobile/start-metro.sh +0 -41
- package/adapters/mobile/verify.sh +19 -64
- package/adapters/mobile/wait-for-bridge.sh +22 -8
- package/adapters/shared/resolve-slot-ports-core.mjs +17 -6
- package/adapters/shared/resolve-slot-ports.sh +17 -5
- package/adapters/shared/update-check-worker.mjs +43 -0
- package/bin/mm-harness +21 -2
- package/dist/adapters/core/surface.js +4 -1
- package/dist/adapters/extension/console-capture.js +95 -0
- package/dist/adapters/extension/product-config.js +110 -0
- package/dist/adapters/extension/runtime-decision.js +20 -2
- package/dist/adapters/extension/surface.js +22 -3
- package/dist/adapters/mobile/perps-env.js +43 -3
- package/dist/adapters/mobile/prepare.js +39 -7
- package/dist/adapters/mobile/surface.js +5 -2
- package/dist/adapters/resolve-slot-ports.js +2 -2
- package/dist/adapters/slot-ports.js +13 -16
- package/dist/adapters.js +56 -16
- 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 +7 -14
- package/dist/command-contract.js +451 -0
- package/dist/command-journal.js +225 -0
- package/dist/commands/call.js +170 -50
- package/dist/commands/check.js +9 -3
- package/dist/commands/completion-candidates.js +20 -13
- package/dist/commands/device-target.js +27 -12
- package/dist/commands/doctor.js +106 -25
- package/dist/commands/fixtures.js +92 -34
- package/dist/commands/flows.js +39 -10
- package/dist/commands/last.js +52 -0
- package/dist/commands/launch/extension.js +38 -15
- package/dist/commands/launch/index.js +207 -63
- package/dist/commands/list-executables.js +151 -29
- package/dist/commands/logs.js +8 -6
- package/dist/commands/manifest.js +270 -35
- package/dist/commands/parse-args.js +13 -1
- package/dist/commands/provision.js +10 -3
- package/dist/commands/run-engine.js +435 -105
- package/dist/commands/run-report.js +12 -3
- package/dist/commands/run.js +355 -50
- package/dist/commands/shared.js +75 -3
- package/dist/commands/status-probe.js +4 -1
- package/dist/commands/status.js +2 -1
- package/dist/commands/stop.js +7 -2
- package/dist/commands/update.js +16 -28
- package/dist/completions-cache.js +1 -1
- package/dist/doctor.js +57 -10
- package/dist/harness.js +47 -137
- package/dist/heal-bounds.js +2 -2
- package/dist/json-stream.js +57 -0
- package/dist/live-adapter-contract.js +138 -32
- package/dist/manifest.js +161 -1
- package/dist/mm-harness-cli.js +135 -54
- package/dist/paths.js +2 -5
- package/dist/recipe-security.js +178 -0
- package/dist/run-diagnostics.js +261 -0
- package/dist/runner.js +117 -8
- 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/README.md +4 -0
- package/library/actions/core/perps/_controller.mjs +10 -55
- 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/wallet/list_accounts.mjs +37 -0
- package/library/manifests/core.action-manifest.json +68 -7
- package/library/manifests/extension.action-manifest.json +53 -0
- package/library/manifests/mobile.action-manifest.json +81 -3
- package/library/recipes/runner/action-validation.extension.recipe.json +8 -1
- package/library/recipes/runner/action-validation.mobile.recipe.json +8 -1
- package/library/recipes/runner/smoke.core.recipe.json +27 -0
- package/library/recipes/wallet/smoke.extension.recipe.json +42 -0
- package/library/recipes/wallet/smoke.mobile.recipe.json +42 -0
- package/package.json +12 -5
- package/scripts/completions.sh +7 -7
- package/scripts/validate-human-outcomes.mjs +169 -0
- package/adapters/mobile/overlay/app/dev-tools/AgenticService/AgentStepHud.tsx.patch +0 -185
- package/adapters/mobile/overlay/app/dev-tools/AgenticService/AgenticService.ts.patch +0 -1662
- package/adapters/mobile/overlay/compat/README.md +0 -28
- package/adapters/mobile/overlay/compat/rn81-message-event-source.patch +0 -42
- package/adapters/shared/resolve-farmslot-ports-core.mjs +0 -3
- package/adapters/shared/resolve-farmslot-ports.mjs +0 -5
- package/adapters/shared/resolve-farmslot-ports.sh +0 -7
- package/docs/ADAPTER-SURFACE.md +0 -119
- package/docs/CHEATSHEET.md +0 -61
- package/docs/CLI-SPEC.md +0 -1098
- package/docs/CODE-MAP.md +0 -62
- package/docs/DEBUG-HANDOVER.md +0 -36
- package/docs/MENTAL-MODEL.md +0 -295
- package/docs/UX-PRINCIPLES.md +0 -64
- package/docs/architecture.md +0 -398
- package/docs/live-adapter-contract.md +0 -188
- package/docs/package-boundaries.md +0 -47
- package/docs/perps-flow-catalog.md +0 -235
- package/docs/recipe-libraries.md +0 -301
- package/docs/runtime-file-conventions.md +0 -36
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Compatibility overlays (historical-commit replay)
|
|
2
|
-
|
|
3
|
-
NOT dead code. These overlays exist for replay/eval runs against OLD product
|
|
4
|
-
commits — e.g. re-running a historical task on a fixed baseline to validate
|
|
5
|
-
prompt or harness changes. A "zero current references" scan will always come
|
|
6
|
-
up empty here by design: the feature's purpose is non-current checkouts.
|
|
7
|
-
|
|
8
|
-
- Purpose: make historical product checkouts bootable/bridgeable under the
|
|
9
|
-
current local toolchain so Recipe v1 evals can replay against them.
|
|
10
|
-
- When it applies: mobile checkouts predating React Native 0.81 polyfill fixes.
|
|
11
|
-
- How it is applied: MANUALLY (no automatic apply logic in this repo).
|
|
12
|
-
The operator or the `/recipe-harness` skill applies the patch reversibly
|
|
13
|
-
before a historical rebuild (`git apply <patch>` in the product checkout,
|
|
14
|
-
`git apply -R` to remove) and records the overlay path in validation
|
|
15
|
-
evidence. `adapters/mobile/inject.sh` does NOT apply these.
|
|
16
|
-
|
|
17
|
-
Kept in the external runner repository, not Farmslot root scripts, so a
|
|
18
|
-
`/recipe-harness` skill can apply the same reversible overlay before a
|
|
19
|
-
historical rebuild and record the overlay path in validation evidence.
|
|
20
|
-
|
|
21
|
-
Listed in adapters/manifest.json (kind: compat-overlay) so the doctor
|
|
22
|
-
verifies the surface and this directory is never flagged as unused again.
|
|
23
|
-
|
|
24
|
-
## Patches
|
|
25
|
-
|
|
26
|
-
- `rn81-message-event-source.patch`: adds a read-only `MessageEvent.prototype.source`
|
|
27
|
-
getter for React Native 0.81 historical checkouts whose bundled polyfill omits
|
|
28
|
-
it while CDP websocket clients expect browser-compatible `MessageEvent` shape.
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
compat-overlay: rn81-message-event-source (historical-checkout replay support)
|
|
2
|
-
|
|
3
|
-
What: patches metamask-mobile shim.js to add a read-only
|
|
4
|
-
MessageEvent.prototype.source getter.
|
|
5
|
-
Why: the harness CDP bridge expects browser-compatible MessageEvent shape;
|
|
6
|
-
pre-RN-0.81 checkouts ship a polyfill that omits .source, so the bridge
|
|
7
|
-
cannot attach when replaying tasks on those historical commits.
|
|
8
|
-
When: only when replaying/evaluating against mobile checkouts older than the
|
|
9
|
-
RN 0.81 upgrade (pre-RN-0.81 checkouts). Never needed on current main.
|
|
10
|
-
How: applied MANUALLY in the historical product checkout —
|
|
11
|
-
git apply <this file> (and `git apply -R` to remove)
|
|
12
|
-
No automatic apply logic exists in this repo. See ../README.md.
|
|
13
|
-
|
|
14
|
-
diff --git a/shim.js b/shim.js
|
|
15
|
-
--- a/shim.js
|
|
16
|
-
+++ b/shim.js
|
|
17
|
-
@@
|
|
18
|
-
if (typeof global.MessageEvent === 'undefined') {
|
|
19
|
-
global.MessageEvent =
|
|
20
|
-
require('react-native/src/private/webapis/html/events/MessageEvent').default;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
+// Historical runner compatibility: React Native 0.81's MessageEvent polyfill
|
|
24
|
-
+// can omit the browser `source` getter expected by CDP websocket clients under
|
|
25
|
-
+// newer Xcode/Hermes toolchains. Keep the getter read-only and null, matching
|
|
26
|
-
+// browser MessageEvent semantics for non-window messages.
|
|
27
|
-
+if (
|
|
28
|
-
+ global.MessageEvent?.prototype &&
|
|
29
|
-
+ !Object.getOwnPropertyDescriptor(global.MessageEvent.prototype, 'source')
|
|
30
|
-
+) {
|
|
31
|
-
+ Object.defineProperty(global.MessageEvent.prototype, 'source', {
|
|
32
|
-
+ configurable: true,
|
|
33
|
-
+ enumerable: true,
|
|
34
|
-
+ get() {
|
|
35
|
-
+ return null;
|
|
36
|
-
+ },
|
|
37
|
-
+ });
|
|
38
|
-
+}
|
|
39
|
-
+
|
|
40
|
-
class AbortError extends Error {
|
|
41
|
-
constructor(message) {
|
|
42
|
-
super(message);
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Back-compat shim: this leaf is now resolve-slot-ports.mjs. Delegates to it for one
|
|
3
|
-
// release so `node resolve-farmslot-ports.mjs <fn> <repo>` keeps working (the new CLI
|
|
4
|
-
// reads the same argv positions on import).
|
|
5
|
-
import './resolve-slot-ports.mjs';
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Back-compat shim: this wrapper is now resolve-slot-ports.sh. Sources it for one
|
|
3
|
-
# release so old callers keep the same sourced function names (including the
|
|
4
|
-
# resolve_farmslot_ports_by_repo alias defined there).
|
|
5
|
-
_SHIM_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
# shellcheck disable=SC1091
|
|
7
|
-
. "$_SHIM_DIR/resolve-slot-ports.sh"
|
package/docs/ADAPTER-SURFACE.md
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
# The adapter surface — one seam for per-platform behavior
|
|
2
|
-
|
|
3
|
-
`mm-harness` runs against three platforms (mobile | extension | core). The
|
|
4
|
-
danger is that every command re-derives "what does this platform do?" with its
|
|
5
|
-
own `if (adapter === 'mobile') … else if (adapter === 'extension') …` ladder.
|
|
6
|
-
When it does, a platform gets forgotten in one command but not another — the
|
|
7
|
-
class of bug where `doctor` reported a live runtime section for mobile only,
|
|
8
|
-
`stop` refused every non-mobile adapter, and `logs` knew a single extension log
|
|
9
|
-
file instead of all three. Those are *platform-blind* commands.
|
|
10
|
-
|
|
11
|
-
The **adapter surface** is the fix: one interface per platform, resolved through
|
|
12
|
-
a registry, that owns the behavior a command would otherwise branch on.
|
|
13
|
-
|
|
14
|
-
## The interface
|
|
15
|
-
|
|
16
|
-
`src/adapters/surface.ts` defines `AdapterSurface` and the registry
|
|
17
|
-
`getAdapterSurface(adapter)`. Each platform ships one implementation:
|
|
18
|
-
|
|
19
|
-
- `src/adapters/mobile/surface.ts`
|
|
20
|
-
- `src/adapters/extension/surface.ts`
|
|
21
|
-
- `src/adapters/core/surface.ts`
|
|
22
|
-
|
|
23
|
-
```ts
|
|
24
|
-
interface AdapterSurface {
|
|
25
|
-
readonly adapter: MetaMaskRecipeAdapter;
|
|
26
|
-
readonly headless: boolean; // core runs no app/dev server
|
|
27
|
-
resolveSlotPorts(target: string): void; // context > pool > formula (no-op for core)
|
|
28
|
-
runtimeStatus(target: string): Promise<AdapterRuntimeStatus>; // read-only readiness for doctor
|
|
29
|
-
devServer: {
|
|
30
|
-
describe(): string; // "Metro" | "webpack watcher" | "no dev server (headless)"
|
|
31
|
-
stop(target: string): AdapterDevServerStop; // idempotent, slot-scoped; headless = teach
|
|
32
|
-
};
|
|
33
|
-
logSources(target: string): AdapterLogSource[]; // ordered candidate log files (empty for core)
|
|
34
|
-
hints: { launch: string; relaunch: string }; // platform-phrased Next: hints
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
`runtimeStatus` returns a normalized shape so `doctor` renders one line the same
|
|
39
|
-
way for every platform:
|
|
40
|
-
|
|
41
|
-
```ts
|
|
42
|
-
interface AdapterRuntimeStatus {
|
|
43
|
-
decision: string;
|
|
44
|
-
reasonCode?: string;
|
|
45
|
-
reasons: string[];
|
|
46
|
-
deps?: string;
|
|
47
|
-
devServer?: { label: string; status: string }; // absent for headless core
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
The implementations are thin: they delegate to the readiness/port plumbing that
|
|
52
|
-
already existed (`decideExtensionReadiness`, `mobileRuntimeStatus`, the slot-port
|
|
53
|
-
resolvers and the webpack-watcher stop, all re-homed to
|
|
54
|
-
`src/adapters/slot-ports.ts`). The surface is an organizing seam, not a rewrite.
|
|
55
|
-
|
|
56
|
-
## The rule
|
|
57
|
-
|
|
58
|
-
**A command never branches on adapter for behavior the surface owns.**
|
|
59
|
-
|
|
60
|
-
- Do not write `if (adapter === 'core')` — ask `surface.headless`.
|
|
61
|
-
- Do not write `adapter === 'mobile' ? metroPorts() : extensionPorts()` — call
|
|
62
|
-
`surface.resolveSlotPorts(target)`.
|
|
63
|
-
- Do not print `adapter === 'mobile' ? 'mm-harness launch ios' : 'mm-harness
|
|
64
|
-
launch'` — use `surface.hints.launch`.
|
|
65
|
-
|
|
66
|
-
A new platform behavior is added by **extending the surface** (a new member on
|
|
67
|
-
the interface plus its three implementations), never by adding another branch to
|
|
68
|
-
a command. TypeScript then makes it impossible to ship a platform that forgot the
|
|
69
|
-
new member, because each implementation is annotated `: AdapterSurface`.
|
|
70
|
-
|
|
71
|
-
What the surface deliberately does **not** own: a command may still branch on
|
|
72
|
-
adapter for a *mechanism* that is genuinely platform-specific and not part of the
|
|
73
|
-
interface — e.g. `fixtures set` uses a shell arm on mobile and the engine path on
|
|
74
|
-
extension. Those branches select a mechanism; they never re-derive readiness,
|
|
75
|
-
ports, log locations, dev-server lifecycle, or Next: phrasing, which are the
|
|
76
|
-
surface's responsibility.
|
|
77
|
-
|
|
78
|
-
## Migration status
|
|
79
|
-
|
|
80
|
-
Every command that used to branch on adapter now resolves through the surface:
|
|
81
|
-
|
|
82
|
-
| command | surface-backed | uses |
|
|
83
|
-
| --- | --- | --- |
|
|
84
|
-
| `doctor` | yes | `resolveSlotPorts` + `runtimeStatus` (mobile/extension/core runtime section) |
|
|
85
|
-
| `launch` | yes | `resolveSlotPorts` |
|
|
86
|
-
| `stop` | yes | `resolveSlotPorts` + `devServer.stop` (+ headless teaching) |
|
|
87
|
-
| `logs` | yes | `logSources` + `hints.launch` + `headless` |
|
|
88
|
-
| `debug` | yes | `headless` + `hints.relaunch` (core teaching); flag semantics stay per-command |
|
|
89
|
-
| `fixtures` | yes | `headless` + `hints` (retry/launch); the set *mechanism* stays per-platform |
|
|
90
|
-
| `run` / `call` | n/a | engine path; core-headless is handled by the heal contract, not the surface |
|
|
91
|
-
| `flows` | no (by design) | recipe-library flows are adapter-global; not a platform-owned behavior |
|
|
92
|
-
| `completion-candidates` | partial | `actions` scope to the detected checkout adapter; `flows` are adapter-global |
|
|
93
|
-
|
|
94
|
-
`flows` is intentionally not surface-backed: a recipe-library flow can compose
|
|
95
|
-
actions across platforms, so flows are adapter-global by design rather than a
|
|
96
|
-
platform-blind gap. `completion-candidates actions` already resolves the adapter
|
|
97
|
-
from the checkout context (cwd/`--target`); only the adapter-global `flows`
|
|
98
|
-
candidates are unscoped, matching the flows model.
|
|
99
|
-
|
|
100
|
-
## How this composes with the UX principles
|
|
101
|
-
|
|
102
|
-
`docs/UX-PRINCIPLES.md` principle 1 (*Context-aware by default* — "output is
|
|
103
|
-
scoped to the platform… help, flag lists, and completion candidates shrink to
|
|
104
|
-
what applies here") states the intent. The adapter surface is its **enforcement
|
|
105
|
-
mechanism**: a command that resolves platform behavior through the surface is
|
|
106
|
-
context-aware by construction, and one that hand-rolls an adapter ladder is the
|
|
107
|
-
exact failure principle 1 warns against. When adding a command or output path,
|
|
108
|
-
satisfy principle 1 by going through the surface.
|
|
109
|
-
|
|
110
|
-
## Adding a platform behavior — checklist
|
|
111
|
-
|
|
112
|
-
1. Add the member to `AdapterSurface` in `src/adapters/surface.ts`.
|
|
113
|
-
2. Implement it in all three `src/adapters/*/surface.ts` (TypeScript will not
|
|
114
|
-
compile until you do).
|
|
115
|
-
3. Have the command call `getAdapterSurface(adapter).<member>` instead of
|
|
116
|
-
branching.
|
|
117
|
-
4. Cover the closed blind spot with a contract test (see
|
|
118
|
-
`tests/contract/adapter-surface.test.sh`), and keep the registry-completeness
|
|
119
|
-
assertion green.
|
package/docs/CHEATSHEET.md
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# mm-harness — user cheatsheet
|
|
2
|
-
|
|
3
|
-
`mm-harness <command> [target] [flags]` · Run from inside any MetaMask checkout · Platform auto-detected
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Daily loop
|
|
8
|
-
|
|
9
|
-
| Situation | Command |
|
|
10
|
-
|---|---|
|
|
11
|
-
| Start / relaunch iOS | `mm-harness launch ios` |
|
|
12
|
-
| Start / relaunch Android | `mm-harness launch android` |
|
|
13
|
-
| Launch extension (fullscreen) | `mm-harness launch` |
|
|
14
|
-
| Launch extension in sidepanel | `mm-harness launch --sidepanel` |
|
|
15
|
-
| Native code changed — rebuild first | `mm-harness launch ios --build` |
|
|
16
|
-
| Tail Metro / webpack logs | `mm-harness logs` |
|
|
17
|
-
| Open DevTools / RN inspector | `mm-harness debug` |
|
|
18
|
-
| Seed wallet from fixture — no typing | `mm-harness fixtures set` |
|
|
19
|
-
| Refresh wallet fixture files on slot | `mm-harness fixtures sync` |
|
|
20
|
-
|
|
21
|
-
`launch` auto-installs the overlay on first use.
|
|
22
|
-
`fixtures set` reads the password **from** the fixture — never typed.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Proof loop
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
actions → call <action> → flows → run recipe.json --plan → run recipe.json
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
| Command | What it does |
|
|
33
|
-
|---|---|
|
|
34
|
-
| `mm-harness actions` | Action vocabulary for this adapter |
|
|
35
|
-
| `mm-harness call unlock` | One action through the real engine (fuzzy name ok) |
|
|
36
|
-
| `mm-harness flows` | Reusable flows (personal > team > canonical) |
|
|
37
|
-
| `mm-harness run recipe.json --plan` | Validate + print plan, no device touched; exit 5 if invalid |
|
|
38
|
-
| `mm-harness run recipe.json` | Execute + write evidence (summary / trace / artifacts) |
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## Health
|
|
43
|
-
|
|
44
|
-
| Command | What it does |
|
|
45
|
-
|---|---|
|
|
46
|
-
| `mm-harness doctor` | Full readiness check — fixture, runtime context, overlay. No launch. |
|
|
47
|
-
| `mm-harness doctor --fix` | Repair overlay + runtime context without launching the app. |
|
|
48
|
-
| `mm-harness verify` | Check overlay/runtime is present and healthy. No launch. |
|
|
49
|
-
| `mm-harness cleanup` | Remove the overlay and restore the checkout. |
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## For agents and scripts
|
|
54
|
-
|
|
55
|
-
**`--json`** — machine-readable output on every command; includes `recovered[]`, `mutations[]`, `schemaVersion`.
|
|
56
|
-
|
|
57
|
-
**`--heal`** — `off` (fail fast, repro-preserving) · `infra-only` (heal transport, never wallet; `run`/`call` default) · `auto` (auto-ensure overlay + heal; `launch` default).
|
|
58
|
-
|
|
59
|
-
**Exit codes** — `0` success · `1` recipe/action failed · `2` bad args / missing target · `5` validation failure (fix recipe).
|
|
60
|
-
|
|
61
|
-
**Tab completion** — `mm-harness completions install` prints the lines to add to `~/.zshrc` / `~/.bashrc`.
|