@deeeed/metamask-harness 0.6.1 → 0.6.2

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 CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.2 - 2026-07-06
4
+
5
+ ### Added
6
+ - **`-v` / `--version`** prints the mm-harness version.
7
+
8
+ ### Fixed
9
+ - **`logs` now streams live and shows the file path** — it captured output via spawnSync (never shown for a `tail -F` that doesn't exit), so `logs`/`logs --full` looked dead. New spawnInherit hands the terminal to the follow; the resolved log path + `tail -f`/`less +F` hints print upfront so you can page it yourself. Honors the test override seam.
10
+ - **`debug` resolves the checkout's own port** (slot context → pool → formula) like launch/stop/doctor — bare `mm-harness debug` no longer 'fetch failed' against the wrong port.
11
+
3
12
  ## 0.6.1 - 2026-07-06
4
13
 
5
14
  Fresh-install fixes found live on a published-0.6.0 install.
@@ -10,6 +19,7 @@ Fresh-install fixes found live on a published-0.6.0 install.
10
19
 
11
20
  ### Internal
12
21
  - Reap-checkout-metros test hardened against a SIGTERM timing flake (polls for exit).
22
+
13
23
  ## 0.6.0 - 2026-07-06
14
24
 
15
25
  Minor release: CLI hardening (decomposed, single-parser, dist-only) plus a
@@ -41,6 +51,7 @@ independently cross-reviewed.
41
51
  `ensure_unlocked` fails teaching `fixtures set` on an un-onboarded wallet instead
42
52
  of vacuously passing (mobile + extension); `provision --json` usage errors emit the
43
53
  standard envelope; deps-not-ready teaches a command that works on a bare checkout.
54
+
44
55
  ## 0.5.1 - 2026-07-05
45
56
 
46
57
  Fresh-install hotfixes found in live validation of 0.5.0.
@@ -11,6 +11,7 @@ async function handleDebug(argv) {
11
11
  if (!adapter) return usageOut(json, "debug", `could not detect the MetaMask repo type for ${target}`, ADAPTER_DETECT_NEXT);
12
12
  const surface = getAdapterSurface(adapter);
13
13
  if (surface.headless) return usageOut(json, "debug", "core is headless; there is no debug console.", surface.hints.relaunch);
14
+ surface.resolveSlotPorts(target);
14
15
  const worker = flag(options, "worker");
15
16
  const devMenu = flag(options, "devMenu");
16
17
  if (adapter === "mobile" && worker) {
@@ -2,7 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { runnerDir } from "../paths.js";
4
4
  import { getAdapterSurface } from "../adapters/surface.js";
5
- import { ADAPTER_DETECT_NEXT, EXIT, flag, parseFlags, resolveAdapter, spawnScript, str, targetOf, usageOut } from "./shared.js";
5
+ import { ADAPTER_DETECT_NEXT, EXIT, flag, parseFlags, resolveAdapter, spawnInherit, str, targetOf, usageOut } from "./shared.js";
6
6
  const LOGS_BOOLEANS = /* @__PURE__ */ new Set(["full", "json"]);
7
7
  async function handleLogs(argv) {
8
8
  const { options } = parseFlags(argv, LOGS_BOOLEANS);
@@ -43,30 +43,28 @@ async function handleLogs(argv) {
43
43
  surface.hints.launch
44
44
  );
45
45
  }
46
+ if (json) {
47
+ console.log(JSON.stringify({ schemaVersion: 1, command: "logs", adapter, source, logFile, exitCode: EXIT.ok }, null, 2));
48
+ return EXIT.ok;
49
+ }
50
+ process.stderr.write(
51
+ `${source} log: ${logFile}
52
+ tail it yourself: tail -f ${logFile} \xB7 page it: less +F ${logFile}
53
+ following below (Ctrl-C to stop) \u2026
54
+ `
55
+ );
46
56
  const full = flag(options, "full");
47
57
  if (full) {
48
- const result2 = spawnScript("tail", ["-n", "+1", "-F", logFile], target, json);
49
- return result2.status === 0 ? EXIT.ok : EXIT.runtime;
58
+ return spawnInherit("tail", ["-n", "+1", "-F", logFile], target) === 0 ? EXIT.ok : EXIT.runtime;
50
59
  }
51
60
  const logTui = path.join(runnerDir, "adapters/shared/log-tui.mjs");
52
61
  const eventCount = process.env.RECIPE_LOG_EVENTS ?? "20";
53
62
  const uiMode = process.env.RECIPE_LOG_UI_MODE ?? "compact";
54
- const result = spawnScript(
63
+ return spawnInherit(
55
64
  process.execPath,
56
65
  [logTui, "tail", "--log", logFile, "--events", eventCount, "--follow", "--mode", uiMode],
57
- target,
58
- json
59
- );
60
- if (json) {
61
- console.log(
62
- JSON.stringify(
63
- { schemaVersion: 1, command: "logs", adapter, source, logFile, exitCode: result.status === 0 ? EXIT.ok : EXIT.runtime },
64
- null,
65
- 2
66
- )
67
- );
68
- }
69
- return result.status === 0 ? EXIT.ok : EXIT.runtime;
66
+ target
67
+ ) === 0 ? EXIT.ok : EXIT.runtime;
70
68
  }
71
69
  export {
72
70
  handleLogs
@@ -85,6 +85,27 @@ function spawnScript(script, args, cwd, json, env) {
85
85
  if (!json && output) process.stderr.write(output);
86
86
  return { status: result.status ?? 1, output };
87
87
  }
88
+ function spawnInherit(script, args, cwd) {
89
+ const isNodeScript = script === process.execPath && args.length > 0;
90
+ const stem = (isNodeScript ? path.basename(args[0]) : path.basename(script)).replace(/[^A-Za-z0-9]/gu, "_").toUpperCase();
91
+ const override = process.env[`MM_HARNESS_SCRIPT_BIN_${stem}`];
92
+ const bin = override ?? script;
93
+ const directArgs = override !== void 0 && isNodeScript ? args.slice(1) : args;
94
+ const { bin: invokeBin, args: spawnArgs } = resolveLeafInvoke(bin, directArgs);
95
+ const result = spawnSync(invokeBin, spawnArgs, { cwd, stdio: "inherit", env: process.env });
96
+ if (result.error) {
97
+ const leaf = isNodeScript ? path.basename(args[0]) : path.basename(script);
98
+ const code = result.error.code ?? "ESPAWN";
99
+ process.stderr.write(
100
+ `leaf could not start: ${leaf} (${code})
101
+ Next: reinstall mm-harness (npm i -g @deeeed/metamask-harness) \u2014 the leaf is missing or not executable
102
+ `
103
+ );
104
+ return 1;
105
+ }
106
+ if (result.status !== null) return result.status;
107
+ return result.signal === "SIGINT" || result.signal === "SIGTERM" ? 0 : 1;
108
+ }
88
109
  function spawnScriptStreaming(script, args, cwd, env) {
89
110
  const isNodeScript = script === process.execPath && args.length > 0;
90
111
  const stem = isNodeScript ? path.basename(args[0]).replace(/[^A-Za-z0-9]/gu, "_").toUpperCase() : path.basename(script).replace(/[^A-Za-z0-9]/gu, "_").toUpperCase();
@@ -149,6 +170,7 @@ export {
149
170
  flag,
150
171
  parseFlags,
151
172
  resolveAdapter,
173
+ spawnInherit,
152
174
  spawnScript,
153
175
  spawnScriptStreaming,
154
176
  str,
@@ -469,8 +469,15 @@ function translateActionsRaw(argv) {
469
469
  const withJson = rest.includes("--json") ? rest : [...rest, "--json"];
470
470
  return ["manifest", ...withJson];
471
471
  }
472
+ const pkgVersion = (() => {
473
+ try {
474
+ return JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8")).version ?? "unknown";
475
+ } catch {
476
+ return "unknown";
477
+ }
478
+ })();
472
479
  const program = new Command();
473
- program.name("mm-harness").description("the MetaMask recipe harness: launch the app, prove behavior, manage the runtime overlay").helpOption("-h, --help", "Show grouped help").showHelpAfterError("(run `mm-harness --help` for the full surface)").configureHelp({ formatHelp: () => groupedHelp() });
480
+ program.name("mm-harness").description("the MetaMask recipe harness: launch the app, prove behavior, manage the runtime overlay").version(pkgVersion, "-v, --version", "Print the mm-harness version").helpOption("-h, --help", "Show grouped help").showHelpAfterError("(run `mm-harness --help` for the full surface)").configureHelp({ formatHelp: () => groupedHelp() });
474
481
  for (const command of REAL) {
475
482
  program.command(command.name).description(command.summary).allowUnknownOption().helpOption("-h, --help", "Show command help").configureHelp({ formatHelp: () => `${command.helpText}
476
483
  ` }).argument("[args...]").action(async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deeeed/metamask-harness",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mm-harness": "bin/mm-harness"