@deeeed/metamask-harness 0.2.0 → 0.3.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.
Files changed (109) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +20 -17
  3. package/{orchestration → adapters}/core/cleanup.sh +2 -2
  4. package/{orchestration → adapters}/core/inject.sh +8 -8
  5. package/{orchestration → adapters}/extension/cleanup.mjs +1 -1
  6. package/{orchestration → adapters}/extension/console-tail.mjs +3 -0
  7. package/{orchestration → adapters}/extension/ensure-browser.sh +4 -4
  8. package/{orchestration → adapters}/extension/inject.mjs +27 -31
  9. package/{orchestration → adapters}/extension/launch.sh +4 -4
  10. package/{orchestration → adapters}/extension/live.sh +5 -5
  11. package/{orchestration → adapters}/extension/readiness.mjs +12 -2
  12. package/{orchestration → adapters}/extension/refresh-build.sh +1 -1
  13. package/{orchestration → adapters}/extension/seed-fixture.sh +1 -1
  14. package/{orchestration → adapters}/extension/start-watch.sh +7 -7
  15. package/{runner → adapters}/extension/verify.sh +11 -11
  16. package/{orchestration → adapters}/extension/wallet-fixture-state.cjs +2 -2
  17. package/{orchestration → adapters}/manifest.json +96 -96
  18. package/{library/actions → adapters}/mobile/bridge-runtime/cdp-bridge.cjs +5 -5
  19. package/{orchestration → adapters}/mobile/cleanup.sh +3 -3
  20. package/{orchestration → adapters}/mobile/inject.sh +22 -24
  21. package/adapters/mobile/open-device.sh +250 -0
  22. package/{orchestration/compat-overlays → adapters/mobile/overlay/compat}/README.md +13 -4
  23. package/adapters/mobile/prewarm-bundle.sh +95 -0
  24. package/adapters/mobile/start-metro.sh +228 -0
  25. package/{runner → adapters}/mobile/verify.sh +6 -6
  26. package/adapters/mobile/wait-for-bridge.sh +108 -0
  27. package/adapters/mobile/yarn-setup.sh +20 -0
  28. package/{orchestration/lib → adapters/shared}/cli-ux.sh +5 -9
  29. package/{orchestration/lib → adapters/shared}/log-tui.mjs +57 -1
  30. package/{orchestration/lib → adapters/shared}/open-debug.mjs +32 -10
  31. package/{orchestration/lib → adapters/shared}/resolve-farmslot-ports.sh +47 -0
  32. package/adapters/shared/sync-wallet-fixture.sh +78 -0
  33. package/bin/mm-harness +5 -6
  34. package/docs/CLI-SPEC.md +41 -2
  35. package/docs/architecture.md +69 -38
  36. package/docs/runtime-file-conventions.md +3 -3
  37. package/library/actions/core/perps/_controller.mjs +1 -1
  38. package/library/actions/extension/platform/cdp.mjs +2 -2
  39. package/library/actions/extension/wallet/ensure_unlocked.mjs +1 -1
  40. package/library/actions/mobile/platform/bridge.mjs +1 -1
  41. package/library/actions/mobile/wallet/ensure_unlocked.mjs +1 -1
  42. package/library/actions/mobile/wallet/setup.mjs +2 -2
  43. package/library/library.json +1 -1
  44. package/package.json +8 -8
  45. package/{orchestration → src/adapters}/extension/runtime-decision.ts +5 -5
  46. package/{orchestration → src/adapters}/extension/runtime.ts +1 -1
  47. package/src/adapters/mobile/prepare.ts +210 -0
  48. package/{orchestration → src/adapters}/mobile/runtime-decision.ts +11 -3
  49. package/{runner/src → src}/adapters.ts +3 -3
  50. package/{orchestration/lib/cli-color.mjs → src/cli-color.ts} +21 -13
  51. package/{orchestration/lib/cli-commands.mjs → src/cli-commands.ts} +52 -45
  52. package/{orchestration/lib/cli-version.mjs → src/cli-version.ts} +35 -17
  53. package/{runner/src → src}/cli.ts +25 -18
  54. package/src/commands/debug.ts +61 -0
  55. package/src/commands/fixtures.ts +196 -0
  56. package/{runner/src → src}/commands/launch.ts +185 -41
  57. package/src/commands/logs.ts +86 -0
  58. package/{runner/src → src}/commands/shared.ts +26 -26
  59. package/{runner/src → src}/harness.ts +97 -10
  60. package/src/index.ts +15 -0
  61. package/{runner/src → src}/live-adapter-contract.ts +1 -1
  62. package/{runner/src → src}/mm-harness-cli.ts +19 -3
  63. package/{runner/src → src}/paths.ts +2 -2
  64. package/{orchestration/lib/progress.mjs → src/progress.ts} +31 -21
  65. package/docs/extension-runtime-commands.md +0 -60
  66. package/docs/harness-cli.md +0 -43
  67. package/orchestration/compat-overlays/mobile/README.md +0 -13
  68. package/orchestration/doctor.mjs +0 -72
  69. package/orchestration/lib/cli-home.mjs +0 -354
  70. package/orchestration/lib/recipe-paths.mjs +0 -26
  71. package/orchestration/mobile/launch.sh +0 -137
  72. package/orchestration/mobile/live.sh +0 -125
  73. package/orchestration/porcelain/metamask-recipe +0 -99
  74. package/orchestration/porcelain/mm-recipe +0 -1591
  75. package/orchestration/porcelain/mme-recipe +0 -1181
  76. package/runner/src/commands/debug.ts +0 -44
  77. package/runner/src/commands/fixtures.ts +0 -99
  78. package/runner/src/commands/logs.ts +0 -60
  79. package/runner/src/index.ts +0 -6
  80. /package/{orchestration → adapters}/extension/launch-browser.cjs +0 -0
  81. /package/{orchestration → adapters}/extension/pin-remote-flags.cjs +0 -0
  82. /package/{orchestration → adapters}/extension/sidepanel-toggle.sh +0 -0
  83. /package/{orchestration → adapters}/extension/snapshot-dist.sh +0 -0
  84. /package/{library/actions → adapters}/mobile/bridge-runtime/lib/cdp-eval.cjs +0 -0
  85. /package/{library/actions → adapters}/mobile/bridge-runtime/lib/config.cjs +0 -0
  86. /package/{library/actions → adapters}/mobile/bridge-runtime/lib/issue-capture.cjs +0 -0
  87. /package/{library/actions → adapters}/mobile/bridge-runtime/lib/target-discovery.cjs +0 -0
  88. /package/{library/actions → adapters}/mobile/bridge-runtime/lib/ws-client.cjs +0 -0
  89. /package/{library/actions → adapters}/mobile/bridge-runtime/setup-wallet.sh +0 -0
  90. /package/{library/actions/mobile/app-overlay → adapters/mobile/overlay}/app/dev-tools/AgenticService/AgentStepHud.tsx.patch +0 -0
  91. /package/{library/actions/mobile/app-overlay → adapters/mobile/overlay}/app/dev-tools/AgenticService/AgenticService.ts.patch +0 -0
  92. /package/{orchestration/compat-overlays/mobile → adapters/mobile/overlay/compat}/rn81-message-event-source.patch +0 -0
  93. /package/{orchestration/lib → adapters/shared}/activate-repo-node.sh +0 -0
  94. /package/{orchestration/lib → adapters/shared}/ensure-runner-deps.sh +0 -0
  95. /package/{orchestration/lib → adapters/shared}/harness-path.sh +0 -0
  96. /package/{orchestration/lib → adapters/shared}/hash-helpers.sh +0 -0
  97. /package/{orchestration/lib → adapters/shared}/json-field.sh +0 -0
  98. /package/{orchestration/lib → adapters/shared}/path-defaults.json +0 -0
  99. /package/{orchestration → src/adapters}/extension/ensure-ready.ts +0 -0
  100. /package/{orchestration → src/adapters}/extension/extension-id.ts +0 -0
  101. /package/{orchestration → src/adapters}/mobile/deps-markers.ts +0 -0
  102. /package/{runner/src → src}/completions-cache.ts +0 -0
  103. /package/{runner/src → src}/doctor.ts +0 -0
  104. /package/{runner/src → src}/heal-bounds.ts +0 -0
  105. /package/{runner/src → src}/manifest.ts +0 -0
  106. /package/{runner/src → src}/recording-target.ts +0 -0
  107. /package/{runner/src → src}/run-recording.ts +0 -0
  108. /package/{runner/src → src}/runner.ts +0 -0
  109. /package/{runner/src → src}/types.ts +0 -0
@@ -1,44 +0,0 @@
1
- // debug — open the debug console by composing the porcelain: extension `debug`
2
- // (--worker → `debug worker`); mobile `debug` (--dev-menu → `dev-menu`).
3
- // Cross-platform flag misuse teaches (exit 2).
4
-
5
- import { EXIT, flag, parseFlags, resolveAdapter, spawnPorcelain, targetOf, usageOut } from './shared.ts';
6
-
7
- const DEBUG_BOOLEANS = new Set(['worker', 'devMenu', 'json']);
8
-
9
- export async function handleDebug(argv: string[]): Promise<number> {
10
- const { options } = parseFlags(argv, DEBUG_BOOLEANS);
11
- const json = flag(options, 'json');
12
- const target = targetOf(options);
13
- const adapter = resolveAdapter(options, target);
14
-
15
- if (!adapter) return usageOut(json, 'debug', `could not detect the MetaMask repo type for ${target}`);
16
- if (adapter === 'core') return usageOut(json, 'debug', 'core is headless; there is no debug console.');
17
-
18
- const worker = flag(options, 'worker');
19
- const devMenu = flag(options, 'devMenu');
20
- if (adapter === 'mobile' && worker) {
21
- return usageOut(json, 'debug', '--worker is extension-only (service-worker DevTools). Use --dev-menu on mobile.');
22
- }
23
- if (adapter === 'extension' && devMenu) {
24
- return usageOut(json, 'debug', '--dev-menu is mobile-only (RN developer menu). Use --worker on the extension.');
25
- }
26
-
27
- let args: string[];
28
- if (adapter === 'extension') {
29
- args = worker ? ['debug', 'worker'] : ['debug'];
30
- } else {
31
- args = devMenu ? ['dev-menu'] : ['debug'];
32
- }
33
- const result = spawnPorcelain(adapter, args, target, json);
34
- if (json) {
35
- console.log(
36
- JSON.stringify(
37
- { schemaVersion: 1, command: 'debug', adapter, mode: worker ? 'worker' : devMenu ? 'dev-menu' : 'default', exitCode: result.status === 0 ? EXIT.ok : EXIT.runtime },
38
- null,
39
- 2,
40
- ),
41
- );
42
- }
43
- return result.status === 0 ? EXIT.ok : EXIT.runtime;
44
- }
@@ -1,99 +0,0 @@
1
- // fixtures <sync|set> — manage wallet DATA (never overlay/runtime state). `sync`
2
- // re-renders the wallet fixture files; `set` applies THE canonical fixture (SRP/
3
- // password read FROM the fixture, never typed) and always teaches the edit path.
4
-
5
- import fs from 'node:fs';
6
- import path from 'node:path';
7
-
8
- import { walletFixturePath } from '../paths.ts';
9
- import type { MetaMaskRecipeAdapter } from '../types.ts';
10
- import { EXIT, flag, parseFlags, resolveAdapter, spawnPorcelain, str, targetOf, usageOut } from './shared.ts';
11
-
12
- // One node injected from cli.ts so `fixtures set` can reuse the real engine path
13
- // (`call`'s one-node machinery) without a circular import.
14
- export interface CommandDeps {
15
- runOneNode: (
16
- adapter: MetaMaskRecipeAdapter,
17
- action: string,
18
- args: Record<string, string>,
19
- target: string,
20
- actionManifest: string | undefined,
21
- ) => Promise<{ status: 'pass' | 'fail' }>;
22
- }
23
-
24
- const FIXTURES_BOOLEANS = new Set(['json']);
25
-
26
- export async function handleFixtures(argv: string[], deps: CommandDeps): Promise<number> {
27
- const { positional, options } = parseFlags(argv, FIXTURES_BOOLEANS);
28
- const json = flag(options, 'json');
29
- const sub = positional[0];
30
- if (sub !== 'sync' && sub !== 'set') {
31
- return usageOut(json, 'fixtures', 'fixtures requires a subcommand: mm-harness fixtures <sync|set>');
32
- }
33
- const target = targetOf(options);
34
- const adapter = resolveAdapter(options, target);
35
- if (!adapter) return usageOut(json, 'fixtures', `could not detect the MetaMask repo type for ${target}`);
36
- if (adapter === 'core') return usageOut(json, 'fixtures', 'core is headless; it has no wallet fixture.');
37
-
38
- const canonicalFixture = walletFixturePath(target);
39
-
40
- if (sub === 'sync') {
41
- // Re-render the wallet fixture files onto the checkout (wallet DATA only).
42
- const result = spawnPorcelain(adapter, ['sync'], target, json);
43
- if (json) {
44
- console.log(
45
- JSON.stringify(
46
- { schemaVersion: 1, command: 'fixtures', action: 'sync', adapter, fixture: canonicalFixture, exitCode: result.status === 0 ? EXIT.ok : EXIT.runtime },
47
- null,
48
- 2,
49
- ),
50
- );
51
- }
52
- return result.status === 0 ? EXIT.ok : EXIT.runtime;
53
- }
54
-
55
- // set — apply THE canonical wallet fixture (password read FROM the fixture).
56
- // Env-gap resolution (docs/CLI-SPEC.md Part 4): flag > env RECIPE_WALLET_FIXTURE
57
- // > the slot's canonical fixture.
58
- const fixturePath = path.resolve(str(options, 'fixture') ?? process.env.RECIPE_WALLET_FIXTURE ?? canonicalFixture);
59
- let status: 'pass' | 'fail';
60
- if (adapter === 'mobile') {
61
- // Grounded porcelain: mm-recipe setup-wallet [<fixture>].
62
- const result = spawnPorcelain('mobile', ['setup-wallet', fixturePath], target, json);
63
- status = result.status === 0 ? 'pass' : 'fail';
64
- } else {
65
- // Extension has no standalone porcelain set arm — reuse call's one-node
66
- // machinery via the real engine path (metamask.wallet.setup in the manifest).
67
- if (!fs.existsSync(fixturePath)) {
68
- return usageOut(
69
- json,
70
- 'fixtures',
71
- `no wallet fixture at ${fixturePath}.\n Create it (or pass --fixture <path>), then re-run: mm-harness fixtures set`,
72
- );
73
- }
74
- const previousFixtureEnv = process.env.RECIPE_WALLET_FIXTURE;
75
- process.env.RECIPE_WALLET_FIXTURE = fixturePath;
76
- try {
77
- const result = await deps.runOneNode('extension', 'metamask.wallet.setup', {}, target, str(options, 'actionManifest'));
78
- status = result.status;
79
- } finally {
80
- if (previousFixtureEnv === undefined) delete process.env.RECIPE_WALLET_FIXTURE;
81
- else process.env.RECIPE_WALLET_FIXTURE = previousFixtureEnv;
82
- }
83
- }
84
-
85
- // Always teach where to customize the wallet.
86
- const teaching = `Wallet fixture applied. Want different accounts? Edit: ${canonicalFixture}`;
87
- if (json) {
88
- console.log(
89
- JSON.stringify(
90
- { schemaVersion: 1, command: 'fixtures', action: 'set', adapter, fixture: fixturePath, canonicalFixture, status, exitCode: status === 'pass' ? EXIT.ok : EXIT.runtime, message: teaching },
91
- null,
92
- 2,
93
- ),
94
- );
95
- } else {
96
- console.error(teaching);
97
- }
98
- return status === 'pass' ? EXIT.ok : EXIT.runtime;
99
- }
@@ -1,60 +0,0 @@
1
- // logs — tail Metro/webpack + app logs by composing the porcelain `logs` (+
2
- // --full). Teaches (exit 2) when nothing is running for the checkout.
3
-
4
- import fs from 'node:fs';
5
- import path from 'node:path';
6
-
7
- import { recipeRuntimePath } from '../paths.ts';
8
- import { EXIT, flag, parseFlags, resolveAdapter, spawnPorcelain, str, targetOf, usageOut } from './shared.ts';
9
-
10
- const LOGS_BOOLEANS = new Set(['full', 'json']);
11
-
12
- export async function handleLogs(argv: string[]): Promise<number> {
13
- const { options } = parseFlags(argv, LOGS_BOOLEANS);
14
- const json = flag(options, 'json');
15
- const target = targetOf(options);
16
- const adapter = resolveAdapter(options, target);
17
-
18
- if (!adapter) return usageOut(json, 'logs', `could not detect the MetaMask repo type for ${target}`);
19
- if (adapter === 'core') return usageOut(json, 'logs', 'core is headless; there are no app/Metro logs.');
20
-
21
- const source = str(options, 'source') ?? 'metro';
22
- if (source !== 'metro' && source !== 'app') {
23
- return usageOut(json, 'logs', '--source must be metro or app.');
24
- }
25
-
26
- // Env-gap flag (docs/CLI-SPEC.md Part 4): --events sets the compact event count
27
- // the porcelain reads from RECIPE_LOG_EVENTS. Resolution is flag > env > default:
28
- // the flag wins by setting the env; an absent flag leaves the agent/CI env alone.
29
- const events = str(options, 'events');
30
- if (events !== undefined) {
31
- if (!/^\d+$/u.test(events)) return usageOut(json, 'logs', `--events must be numeric (got: ${events}).`);
32
- process.env.RECIPE_LOG_EVENTS = events;
33
- }
34
-
35
- // Nothing running → teaching error pointing at launch. The log file is the
36
- // signal that Metro/webpack has been started for this checkout.
37
- const logFile = recipeRuntimePath(target, adapter === 'mobile' ? 'metro.log' : 'webpack.log');
38
- if (!fs.existsSync(logFile)) {
39
- const launchHint = adapter === 'mobile' ? 'mm-harness launch ios' : 'mm-harness launch';
40
- return usageOut(
41
- json,
42
- 'logs',
43
- `nothing running for this checkout (no ${path.basename(logFile)}).\n Start it first: ${launchHint}`,
44
- );
45
- }
46
-
47
- const args = ['logs'];
48
- if (flag(options, 'full')) args.push('--full');
49
- const result = spawnPorcelain(adapter, args, target, json);
50
- if (json) {
51
- console.log(
52
- JSON.stringify(
53
- { schemaVersion: 1, command: 'logs', adapter, source, logFile, exitCode: result.status === 0 ? EXIT.ok : EXIT.runtime },
54
- null,
55
- 2,
56
- ),
57
- );
58
- }
59
- return result.status === 0 ? EXIT.ok : EXIT.runtime;
60
- }
@@ -1,6 +0,0 @@
1
- // Keep the package entrypoint narrow. CLI internals import path/runtime helpers
2
- // directly so consumers see only the runner factory, manifest, and doctor API.
3
- export { createDoctorReport } from './doctor.ts';
4
- export { loadActionManifest, validateManifest } from './manifest.ts';
5
- export { createMetaMaskExtensionRunner, createMetaMaskMobileRunner, createMetaMaskRunner } from './runner.ts';
6
- export type { CreateMetaMaskRunnerOptions, MetaMaskDoctorReport, MetaMaskRecipeAdapter } from './types.ts';
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes