@deeeed/metamask-harness 0.92.37 → 0.92.39

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
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.92.39 - 2026-10-20
6
+
7
+ ### Added
8
+
9
+ - `mm-harness recipe-validate <recipe.json> [--artifact-manifest <file>] [--artifact-dir <dir>] [--action-manifest <file>] [--json]` validates a recipe and its retained Recipe v1 run package with the shared validator, the same checks publication runs. It exits 1 when the result is invalid. Skills that package PR evidence can validate a run through the task's own harness.
10
+
11
+ ## 0.92.38 - 2026-10-20
12
+
13
+ ### Changed
14
+
15
+ - Pin `@farmslot/handoff` 0.4.1. The learning package that `mm-harness checklist mark` closeout stages is refused as a recovery phrase only when it holds a BIP-39 phrase whose checksum is valid. Before, any run of 12 wordlist words blocked it, including recipe intent prose, JSON keys and node ids. A real phrase still blocks, in JSON, Markdown, YAML, CSV or logs, apart from the misses handoff's README lists (for example, a phrase split across separate multi-word JSON values).
16
+
5
17
  ## 0.92.37 - 2026-10-20
6
18
 
7
19
  ### Changed
@@ -1003,6 +1003,36 @@ Example:
1003
1003
  positionals: [{ label: "action", choices: ["build", "plan", "advise", "advisor-status"] }]
1004
1004
  }
1005
1005
  },
1006
+ {
1007
+ name: "recipe-validate",
1008
+ summary: "Validate a recipe and its retained Recipe v1 artifact package.",
1009
+ example: "mm-harness recipe-validate artifacts/recipe-run/recipe.json --artifact-dir artifacts/recipe-run --json",
1010
+ helpText: `mm-harness recipe-validate <recipe.json> [flags]
1011
+
1012
+ Validates the recipe graph and, with --artifact-dir, the run package beside it:
1013
+ required files, manifest paths and digests, recorded parameters and resolved
1014
+ dependencies. The checks are the shared Recipe v1 validator's. Exits 1 when the
1015
+ result is invalid.
1016
+
1017
+ --artifact-manifest <file> artifact-manifest.json to validate
1018
+ --artifact-dir <dir> Artifact package directory (required files, manifest paths)
1019
+ --action-manifest <file> Runner action manifest for action checks
1020
+ --json Machine-readable result: { status, findings, summary }
1021
+
1022
+ Example:
1023
+ mm-harness recipe-validate artifacts/recipe-run/recipe.json \\
1024
+ --artifact-manifest artifacts/recipe-run/artifact-manifest.json \\
1025
+ --artifact-dir artifacts/recipe-run --json`,
1026
+ contract: {
1027
+ options: options(HELP, JSON, {
1028
+ "--artifact-manifest": value(),
1029
+ "--artifact-dir": value(),
1030
+ "--action-manifest": value()
1031
+ }),
1032
+ positionals: [{ label: "recipe" }],
1033
+ minimumPositionals: 1
1034
+ }
1035
+ },
1006
1036
  {
1007
1037
  name: "provision",
1008
1038
  summary: "Install the cached Runway iOS dev client on a prepared mobile slot (no deps, no Metro).",
@@ -0,0 +1,30 @@
1
+ import { optionFlag, optionString, parseArgs, usageError } from "@farmslot/recipe-cli/harness";
2
+ import { validateRecipeCliInput } from "@farmslot/recipe-runner/cli/support";
3
+ const USAGE = "Usage: mm-harness recipe-validate <recipe.json> [--artifact-manifest <file>] [--artifact-dir <dir>] [--action-manifest <file>] [--json]";
4
+ async function handleRecipeValidate(argv) {
5
+ const parsed = parseArgs(argv);
6
+ const [recipePath, ...extra] = parsed.positional;
7
+ if (!recipePath || extra.length > 0) throw usageError(USAGE);
8
+ const result = await validateRecipeCliInput({
9
+ recipePath,
10
+ actionManifestPath: optionString(parsed.options, "actionManifest"),
11
+ artifactManifestPath: optionString(parsed.options, "artifactManifest"),
12
+ artifactDir: optionString(parsed.options, "artifactDir")
13
+ });
14
+ if (optionFlag(parsed.options, "json")) {
15
+ process.stdout.write(`${JSON.stringify(result, null, 2)}
16
+ `);
17
+ } else {
18
+ const { errors, warnings } = result.summary;
19
+ process.stdout.write(`recipe validation: ${result.status} (${errors} errors, ${warnings} warnings)
20
+ `);
21
+ for (const finding of result.findings) {
22
+ process.stdout.write(`- ${finding.severity} ${finding.code} ${finding.path}: ${finding.message}
23
+ `);
24
+ }
25
+ }
26
+ return result.status === "invalid" ? 1 : 0;
27
+ }
28
+ export {
29
+ handleRecipeValidate
30
+ };
@@ -58,6 +58,7 @@ import { handleHelp } from "./commands/help.js";
58
58
  import { overlayCommandOptions } from "./commands/overlay.js";
59
59
  import { handlePin } from "./commands/pin.js";
60
60
  import { handlePrBody } from "./commands/pr-body.js";
61
+ import { handleRecipeValidate } from "./commands/recipe-validate.js";
61
62
  import { handleProvision } from "./commands/provision.js";
62
63
  import { handleResolveExtension } from "./commands/resolve-extension.js";
63
64
  import { handleRuntimeDecision } from "./commands/runtime-decision.js";
@@ -183,6 +184,7 @@ const PUBLIC_RUN = {
183
184
  },
184
185
  check: { run: handleCheck },
185
186
  "recipe-quality": { run: (args) => handleRecipeQuality(args, cliRecipeQualityOptions) },
187
+ "recipe-validate": { run: handleRecipeValidate },
186
188
  provision: { run: (args) => handleProvision(parseArgs(args)) },
187
189
  install: { run: overlay("install") },
188
190
  verify: { run: overlay("verify") },
@@ -228,7 +230,7 @@ const HELP_GROUPS = [
228
230
  {
229
231
  title: "PROVE",
230
232
  blurb: "run recipes and inspect readiness",
231
- commands: ["run", "last", "doctor", "check", "checklist", "review", "pr-body", "recipe-quality"]
233
+ commands: ["run", "last", "doctor", "check", "checklist", "review", "pr-body", "recipe-quality", "recipe-validate"]
232
234
  },
233
235
  {
234
236
  title: "RUNTIME OVERLAY",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deeeed/metamask-harness",
3
- "version": "0.92.37",
3
+ "version": "0.92.39",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mm-harness": "bin/mm-harness"
@@ -26,7 +26,7 @@
26
26
  "@farmslot/adapter-sdk": "0.25.0",
27
27
  "@farmslot/adapter-web": "0.17.0",
28
28
  "@farmslot/agent-runtime": "0.36.0",
29
- "@farmslot/handoff": "0.3.2",
29
+ "@farmslot/handoff": "0.4.1",
30
30
  "@farmslot/protocol": "0.60.0",
31
31
  "@farmslot/recipe-cli": "0.30.0",
32
32
  "@farmslot/recipe-runner": "0.46.0",