@deeeed/metamask-harness 0.7.4 → 0.7.5
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 +9 -0
- package/adapters/core/cleanup.sh +0 -0
- package/adapters/core/inject.sh +0 -0
- package/adapters/extension/cleanup.mjs +0 -0
- package/adapters/extension/ensure-browser.sh +0 -0
- package/adapters/extension/inject.mjs +0 -0
- package/adapters/extension/launch-browser.cjs +0 -0
- package/adapters/extension/launch.sh +0 -0
- package/adapters/extension/live.sh +0 -0
- package/adapters/extension/readiness.mjs +0 -0
- package/adapters/extension/reattach.sh +0 -0
- package/adapters/extension/refresh-build.sh +0 -0
- package/adapters/extension/seed-fixture.sh +0 -0
- package/adapters/extension/sidepanel-toggle.sh +0 -0
- package/adapters/extension/snapshot-dist.sh +0 -0
- package/adapters/extension/start-watch.sh +0 -0
- package/adapters/extension/verify.sh +0 -0
- package/adapters/extension/wallet-fixture-state.cjs +0 -0
- package/adapters/mobile/bridge-runtime/cdp-bridge.cjs +0 -0
- package/adapters/mobile/bridge-runtime/setup-wallet.sh +0 -0
- package/adapters/mobile/cleanup.sh +0 -0
- package/adapters/mobile/inject.sh +0 -0
- package/adapters/mobile/lib/metro-listener.sh +0 -0
- package/adapters/mobile/lib/tmux-viewer.sh +0 -0
- package/adapters/mobile/open-device.sh +0 -0
- package/adapters/mobile/prewarm-bundle.sh +0 -0
- package/adapters/mobile/start-metro.sh +0 -0
- package/adapters/mobile/stop-metro.sh +0 -0
- package/adapters/mobile/verify.sh +0 -0
- package/adapters/mobile/wait-for-bridge.sh +0 -0
- package/adapters/mobile/yarn-setup.sh +0 -0
- package/adapters/shared/activate-repo-node.sh +0 -0
- package/adapters/shared/activate-repo-ruby.sh +0 -0
- package/adapters/shared/cli-ux.sh +0 -0
- package/adapters/shared/ensure-runner-deps.sh +0 -0
- package/adapters/shared/harness-path.sh +0 -0
- package/adapters/shared/hash-helpers.sh +0 -0
- package/adapters/shared/json-field.sh +0 -0
- package/adapters/shared/open-log-window.sh +0 -0
- package/adapters/shared/reap-checkout-metros.sh +0 -0
- package/adapters/shared/resolve-farmslot-ports.mjs +0 -0
- package/adapters/shared/resolve-farmslot-ports.sh +0 -0
- package/adapters/shared/resolve-slot-ports.mjs +0 -0
- package/adapters/shared/resolve-slot-ports.sh +0 -0
- package/adapters/shared/sync-wallet-fixture.sh +0 -0
- package/adapters/shared/tmux-session.sh +0 -0
- package/dist/adapters/extension/ensure-ready.js +38 -11
- package/dist/commands/launch/index.js +8 -0
- package/package.json +2 -2
- package/scripts/completions.sh +0 -0
- package/scripts/install-completions.sh +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.5 - 2026-07-07
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **`launch --verify` converges duplicate extension home tabs instead of failing prepare forever.** A second bare `home.html` tab can appear beside the operator's slot-titled one outside the harness's control (the extension opens its own tab after the build-freeze reload), and the live verify health gate requires exactly one home tab — but nothing in launch/verify ever collapsed duplicates (`ensureExtensionReady` was only reachable via the retired `ensure-ready` verb), so every preflight retry recounted two tabs and failed. `launch --verify` (extension, with a CDP port) now runs the convergence before the live verify phase.
|
|
7
|
+
- **Convergence keeps the operator's tab.** With multiple home tabs, `ensureExtensionReady` now prunes the extras keeping the preferred tab — attached (another client is driving it) over custom slot title (`<slot-id> — MetaMask`, how operators tell which agent owns a browser) over first listed — instead of closing all and reopening fresh, which discarded the slot title. The deterministic close-all + fresh-open remains as a one-shot fallback when the kept tab fails the health check, and a failed re-listing during the fallback reports `cdp-unreachable` instead of a stale tab count.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- **`EnsureReadyAction` gains `pruned`** — extras were closed keeping the preferred tab; `reopened` now specifically means the pruned keeper failed the health check and one fresh tab was reopened.
|
|
11
|
+
|
|
3
12
|
## 0.7.4 - 2026-07-07
|
|
4
13
|
|
|
5
14
|
### Added
|
package/adapters/core/cleanup.sh
CHANGED
|
File without changes
|
package/adapters/core/inject.sh
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -47,6 +47,12 @@ function homePages(targets, extensionId) {
|
|
|
47
47
|
(t) => t.type === "page" && typeof t.url === "string" && t.url.startsWith(prefix) && t.url.includes("/home.html") && t.id
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
|
+
function pickHomeKeeper(homes) {
|
|
51
|
+
const attached = homes.filter((t) => typeof t.webSocketDebuggerUrl !== "string");
|
|
52
|
+
const pool = attached.length > 0 ? attached : homes;
|
|
53
|
+
const marked = pool.find((t) => typeof t.title === "string" && t.title.trim() !== "" && t.title.trim() !== "MetaMask");
|
|
54
|
+
return marked ?? pool[0];
|
|
55
|
+
}
|
|
50
56
|
async function ensureExtensionReady(target, options) {
|
|
51
57
|
const resolved = path.resolve(target);
|
|
52
58
|
const { cdpPort } = options;
|
|
@@ -91,14 +97,14 @@ async function ensureExtensionReady(target, options) {
|
|
|
91
97
|
opened = await openHome(cdpPort, extensionId) || opened;
|
|
92
98
|
await sleep(1500);
|
|
93
99
|
} else {
|
|
94
|
-
action = "
|
|
100
|
+
action = "pruned";
|
|
101
|
+
const keeper = pickHomeKeeper(homes);
|
|
95
102
|
for (const h of homes) {
|
|
103
|
+
if (h === keeper) continue;
|
|
96
104
|
await closeTab(cdpPort, String(h.id));
|
|
97
105
|
closed += 1;
|
|
98
106
|
}
|
|
99
107
|
await sleep(500);
|
|
100
|
-
opened = await openHome(cdpPort, extensionId) || opened;
|
|
101
|
-
await sleep(1500);
|
|
102
108
|
}
|
|
103
109
|
const next = await jsonList(cdpPort);
|
|
104
110
|
if (!next.ok) {
|
|
@@ -125,14 +131,35 @@ async function ensureExtensionReady(target, options) {
|
|
|
125
131
|
if (!finalListing.ok) {
|
|
126
132
|
return base({ extensionId, opened, action, homeTabs: { before, closed, after: homesNow.length }, reasonCode: "cdp-unreachable" });
|
|
127
133
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
let after = homePages(finalListing.targets, extensionId).length;
|
|
135
|
+
const checkHealth = async () => {
|
|
136
|
+
try {
|
|
137
|
+
const { checkExtensionRuntimeHealth } = await import("./runtime.js");
|
|
138
|
+
const report = await checkExtensionRuntimeHealth(resolved, cdpPort);
|
|
139
|
+
return { status: report.status, findings: report.findings };
|
|
140
|
+
} catch (error) {
|
|
141
|
+
return { status: "FAIL", findings: [error instanceof Error ? error.message : String(error)] };
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
let health = await checkHealth();
|
|
145
|
+
if (action === "pruned" && (health.status !== "PASS" || after !== 1)) {
|
|
146
|
+
const listing = await jsonList(cdpPort);
|
|
147
|
+
if (listing.ok) {
|
|
148
|
+
action = "reopened";
|
|
149
|
+
for (const h of homePages(listing.targets, extensionId)) {
|
|
150
|
+
await closeTab(cdpPort, String(h.id));
|
|
151
|
+
closed += 1;
|
|
152
|
+
}
|
|
153
|
+
await sleep(500);
|
|
154
|
+
opened = await openHome(cdpPort, extensionId) || opened;
|
|
155
|
+
await sleep(1500);
|
|
156
|
+
const relisted = await jsonList(cdpPort);
|
|
157
|
+
if (!relisted.ok) {
|
|
158
|
+
return base({ extensionId, opened, action, homeTabs: { before, closed, after }, reasonCode: "cdp-unreachable" });
|
|
159
|
+
}
|
|
160
|
+
after = homePages(relisted.targets, extensionId).length;
|
|
161
|
+
health = await checkHealth();
|
|
162
|
+
}
|
|
136
163
|
}
|
|
137
164
|
const ready = health.status === "PASS" && after === 1;
|
|
138
165
|
return base({
|
|
@@ -104,6 +104,14 @@ async function handleLaunch(argv) {
|
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
if (tier === "verify") {
|
|
107
|
+
const verifyCdpPort = Number(process.env.CDP_PORT ?? "");
|
|
108
|
+
if (adapter === "extension" && Number.isInteger(verifyCdpPort) && verifyCdpPort > 0) {
|
|
109
|
+
const { ensureExtensionReady } = await import("../../adapters/extension/ensure-ready.js");
|
|
110
|
+
const convergence = await ensureExtensionReady(target, { cdpPort: verifyCdpPort });
|
|
111
|
+
console.error(
|
|
112
|
+
`[launch] home-tab convergence: ${convergence.action} (${convergence.homeTabs.before}\u2192${convergence.homeTabs.after} tabs, closed ${convergence.homeTabs.closed})${convergence.ready ? "" : ` \u2014 ${convergence.reasonCode}`}`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
107
115
|
const liveArgs = ["live", "--adapter", adapter, "--target", target];
|
|
108
116
|
if (adapter === "mobile" && mobileTarget) liveArgs.push("--platform", mobileTarget);
|
|
109
117
|
if (json) liveArgs.push("--json");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deeeed/metamask-harness",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mm-harness": "bin/mm-harness"
|
|
@@ -69,4 +69,4 @@
|
|
|
69
69
|
"url": "https://github.com/MetaMask/experimental-metamask-harness/issues"
|
|
70
70
|
},
|
|
71
71
|
"homepage": "https://github.com/MetaMask/experimental-metamask-harness#readme"
|
|
72
|
-
}
|
|
72
|
+
}
|
package/scripts/completions.sh
CHANGED
|
File without changes
|
|
File without changes
|