{"id":50677086,"url":"https://github.com/deeeed/metamask-recipe-runner","last_synced_at":"2026-06-08T16:05:14.738Z","repository":{"id":362183623,"uuid":"1256704140","full_name":"deeeed/metamask-recipe-runner","owner":"deeeed","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-03T02:11:12.000Z","size":142,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T04:10:40.619Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deeeed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-02T02:45:11.000Z","updated_at":"2026-06-02T02:45:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/deeeed/metamask-recipe-runner","commit_stats":null,"previous_names":["deeeed/metamask-recipe-runner"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/deeeed/metamask-recipe-runner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fmetamask-recipe-runner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fmetamask-recipe-runner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fmetamask-recipe-runner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fmetamask-recipe-runner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deeeed","download_url":"https://codeload.github.com/deeeed/metamask-recipe-runner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeeed%2Fmetamask-recipe-runner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34069511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-08T16:05:13.549Z","updated_at":"2026-06-08T16:05:14.720Z","avatar_url":"https://github.com/deeeed.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MetaMask Recipe Runner\n\nMetaMask-specific runner package for Recipe Protocol v1. This runner consumes the published `@farmslot/protocol` and `@farmslot/recipe-harness` packages, with an explicit local override only for protocol co-development.\n\nThis project owns the MetaMask action catalog, manifests, and live adapters for\nMetaMask Mobile and Extension recipe validation. It intentionally stays outside\n`metamask-skills`: skills are thin UX wrappers that resolve this project, install\nit into `temp/recipe/harness/\u003cadapter\u003e/runner/`, and call `bin/metamask-recipe`.\n\n## Boundary\n\nThe shared action surface is a durable capability contract, not a checklist of\none ticket's acceptance criteria. Add `metamask.*` actions only for\nparameterized product/domain operations that will be reused across many recipes,\nsuch as start-state convergence, read/assert state, placing orders,\nclosing selected positions, or cancelling selected orders.\n\nDo not add shared actions for ticket IDs, POCs, exact test IDs, one-off copy,\nbanner/style/placement assertions, or other task-local proof details. For those\ncases, keep the recipe small and use:\n\n- official `ui.*` actions for visible user interaction and presence checks;\n- screenshot `claims` and artifacts for visual/copy/layout proof;\n- task-local composed flows in the task artifact when a helper is useful only\n  for that task;\n- safe direct read/controller calls for setup or assertions when the visible UI\n  path is not the acceptance criterion.\n\n## HUD intent contract\n\nEvery non-terminal recipe node must include `intent`. The default HUD shows status/progress plus exactly one current intent line. `detail` is hidden unless explicitly configured, errors may appear as the only secondary line, and flow/call nesting stays trace/debug metadata. Mobile uses the same structured HUD payload as Extension when the in-app bridge supports it, with a legacy `show-step` fallback for older checkouts.\n\n## Proof interaction contract\n\nThe action manifest is the executable contract. A Recipe Protocol v1 official action\nis callable only when this runner advertises it in\n`supported_official_actions`; unsupported official actions stay absent until they\nare implemented and proven on both Mobile and Extension.\n\nUse the smallest layer that proves the claim:\n\n- Use `metamask.*` domain actions for setup, teardown, idempotent start state,\n  read/assert checks, and supported product/controller API operations where the\n  visual path would add repetitive setup noise.\n- Use official `ui.*` actions for the interaction window that must be visible in\n  human proof: pressing buttons, entering input, keypad taps, scrolling an item\n  into view, screenshots, and future drag/swipe gestures.\n- Never use direct controller/CDP calls to fake a user-visible acceptance\n  criterion. If the claim is “the UI lets a user do X”, the proof recipe must\n  drive X through `ui.*` and then assert/capture the result.\n- `ui.gesture` is not in the MetaMask manifests yet. Drag/swipe recipes must wait\n  until the runner exposes it and action-validation proves it on Mobile and\n  Extension.\n\nThe current action-validation recipes exercise every manifest-declared action and\nspecifically include both generic `ui.scroll` and the `scroll_into_view` variant\nbefore screenshot proof.\n\n- Farmslot owns the protocol schema, graph execution, trace/summary/artifact\n  package writing, and generic `ui.*`/CDP/React Native transports.\n- This runner owns MetaMask project semantics: `metamask.wallet.*`,\n  `metamask.perps.*`, action manifests, and platform live-adapter bindings.\n- Skills own user-facing install/verify/cook/doctor flows only.\n\n## Required environment\n\nA normal checkout/install should resolve Farmslot through package dependencies:\n`@farmslot/protocol` and `@farmslot/recipe-harness`. `FARMSLOT_ROOT` is only a\nlocal-development override used while changing Farmslot and this runner together.\n\nSkills resolve this runner in this order: explicit local override (`METAMASK_RECIPE_RUNNER_SOURCE` / `RECIPE_RUNNER_SOURCE`), sibling checkout named `metamask-recipe-runner`, npm package, then git fallback.\n\nDuring the ADR-58 pilot the npm package is published under Arthur's personal namespace as `@deeeed/metamask-recipe-runner` so reviewers can reproduce the skills without a local checkout. If ADR-58 is accepted, ownership should migrate to a MetaMask/Consensys namespace and release process.\n\n## Commands\n\n```bash\nbin/metamask-recipe manifest --adapter mobile --json\nbin/metamask-recipe manifest --adapter extension --json\nbin/metamask-recipe actions --adapter mobile --json\nbin/metamask-recipe actions --adapter extension --action ui.press --json\nbin/metamask-recipe doctor --adapter mobile --target /path/to/metamask-mobile --json\nbin/metamask-recipe run recipes/smoke.mobile.recipe.json --adapter mobile --target /path/to/metamask-mobile --artifacts-dir /tmp/mm-smoke --json\nbin/metamask-recipe self-test --artifacts-dir /tmp/metamask-runner-self-test --json\n```\n\n## Local Farmslot co-development\n\nThis repo imports the real Farmslot package names (`@farmslot/protocol` and\n`@farmslot/recipe-harness`) and expects them to be installed like normal runtime\ndependencies. Do not commit relative `../../farmslot` TypeScript paths or local\ntype shims.\n\nWhen actively changing Farmslot packages before publishing, opt into local\nsymlinks explicitly:\n\n```bash\nFARMSLOT_ROOT=/path/to/farmslot npm run dev:link-farmslot\n```\n\nThe check script can also resolve a sibling/local Farmslot checkout and writes\nonly an ignored `.tmp/tsconfig.check.json`.\n\n\n## Recipe quality follow-up: composed start states\n\nThe current runner proves manifest-declared action execution. Recipe v1 should not be treated as production-complete until the runner also publishes reusable flow catalogs for setup/start-state composition. The intended model is:\n\n```text\nmetamask.wallet.ensure_unlocked\nmetamask.perps.close_positions({ mode: \"all\" })\nmetamask.perps.close_orders({ mode: \"all\" })\nmetamask.perps.ensure_positions({ state: \"none\", mode: \"all\" })\nmetamask.perps.ensure_orders({ state: \"none\", mode: \"all\" })\nmetamask.perps.start_state({ network, provider, page, market, positions, orders })\n```\n\n`close_positions` and `close_orders` are primitive bulk operations: selector params decide whether they close one market, several markets, or everything returned by the product. `ensure_*` flows are idempotent convergence wrappers: inspect current state, call the primitive operations only when needed, prove postconditions, and fail if the requested baseline cannot be reached. For Perps, `start_state` should own starting page, mainnet/testnet, provider selection such as Hyperliquid, optional selected market, and optional position/order preconditions. See `docs/perps-flow-catalog.md`.\n\nProof recipes should then record only the AC-specific interaction while setup remains visible in `trace.json`/`summary.json`.\n\n## Validation\n\n```bash\nnpm run check\nnpm run self-test\n```\n\nFor proof-capable actions, run the action-validation recipes on live Mobile and\nExtension targets, then validate the output:\n\n```bash\nnode scripts/validate-action-e2e-artifacts.mjs \u003cartifacts-dir\u003e manifests/mobile.action-manifest.json mobile\nnode scripts/validate-action-e2e-artifacts.mjs \u003cartifacts-dir\u003e manifests/extension.action-manifest.json extension\n```\n\n## TypeScript package surface\n\nThe public runner surface is TypeScript (`src/*.ts`) and exports typed factory, manifest, and doctor contracts from `src/index.ts`. The executable wrapper still invokes Farmslot's `tsx` so installed runners work on Node versions that do not execute `.ts` files directly. Live adapters remain small `.mjs` scripts because they are copied into target checkouts and executed as standalone Node programs.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeeeed%2Fmetamask-recipe-runner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeeeed%2Fmetamask-recipe-runner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeeeed%2Fmetamask-recipe-runner/lists"}