@deeeed/metamask-harness 0.81.0 → 0.82.1

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 (71) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/adapters/manifest.json +51 -51
  3. package/adapters/{terminal → web-dapp}/cleanup.mjs +9 -9
  4. package/adapters/{terminal → web-dapp}/inject.mjs +14 -14
  5. package/adapters/{terminal → web-dapp}/launch.mjs +23 -24
  6. package/adapters/web-dapp/lib/blocked-hosts.mjs +24 -0
  7. package/adapters/{terminal → web-dapp}/lib/cdp-client.mjs +1 -1
  8. package/adapters/{terminal → web-dapp}/lib/display.mjs +1 -1
  9. package/adapters/{terminal → web-dapp}/lib/hud.mjs +1 -1
  10. package/adapters/web-dapp/lib/policy.mjs +79 -0
  11. package/adapters/{terminal → web-dapp}/lib/processes.mjs +8 -8
  12. package/adapters/{terminal → web-dapp}/lib/readiness.mjs +15 -25
  13. package/adapters/{terminal → web-dapp}/stop.mjs +5 -4
  14. package/adapters/{terminal → web-dapp}/verify.mjs +11 -15
  15. package/adapters/{terminal → web-dapp}/wallet-host.mjs +10 -11
  16. package/dist/adapters/extension/run.js +5 -28
  17. package/dist/adapters/plugin-surface.js +98 -0
  18. package/dist/adapters/surface.js +1 -1
  19. package/dist/adapters/{terminal → web-dapp}/actions.js +7 -7
  20. package/dist/adapters/web-dapp/console-capture.js +63 -0
  21. package/dist/adapters/web-dapp/doctor-checks.js +33 -0
  22. package/dist/adapters/{terminal → web-dapp}/launch.js +21 -22
  23. package/dist/adapters/web-dapp/overlay.js +21 -0
  24. package/dist/adapters/web-dapp/readiness.js +10 -0
  25. package/dist/adapters/{terminal → web-dapp}/run.js +15 -15
  26. package/dist/adapters/{terminal → web-dapp}/stop.js +5 -4
  27. package/dist/adapters/web-dapp/surface.js +149 -0
  28. package/dist/cli.js +3 -0
  29. package/dist/command-contract.js +29 -7
  30. package/dist/commands/check.js +5 -4
  31. package/dist/commands/doctor.js +19 -2
  32. package/dist/commands/farmslot-ready.js +1 -0
  33. package/dist/commands/help.js +1 -1
  34. package/dist/commands/launch/device.js +5 -5
  35. package/dist/commands/self-test.js +9 -5
  36. package/dist/engine.js +6 -16
  37. package/dist/manifest.js +48 -24
  38. package/dist/mm-harness-cli.js +17 -0
  39. package/dist/performance-observation.js +7 -13
  40. package/dist/runner.js +26 -7
  41. package/docs/cli-contract.md +5 -3
  42. package/library/actions/shared/console-collector.mjs +1 -1
  43. package/library/actions/{terminal → web-dapp}/app/assert_no_console_errors.mjs +4 -4
  44. package/library/actions/{terminal → web-dapp}/app/launch.mjs +7 -7
  45. package/library/actions/{terminal → web-dapp}/platform/hud.mjs +5 -5
  46. package/library/actions/{terminal → web-dapp}/platform/page.mjs +11 -11
  47. package/library/actions/{terminal → web-dapp}/platform/runtime.mjs +16 -12
  48. package/library/actions/web-dapp/ui/navigate.mjs +24 -0
  49. package/library/actions/web-dapp/wallet/_signature-log.mjs +32 -0
  50. package/library/actions/{terminal → web-dapp}/wallet/assert_signatures.mjs +4 -4
  51. package/library/actions/{terminal → web-dapp}/wallet/list_accounts.mjs +2 -2
  52. package/library/actions/{terminal → web-dapp}/wallet/read_signatures.mjs +6 -6
  53. package/library/manifests/{terminal.action-manifest.json → web-dapp.action-manifest.json} +18 -702
  54. package/package.json +5 -5
  55. package/adapters/terminal/lib/mainnet-guard.mjs +0 -186
  56. package/adapters/terminal/policy.mjs +0 -35
  57. package/dist/adapters/terminal/console-capture.js +0 -59
  58. package/dist/adapters/terminal/doctor-checks.js +0 -24
  59. package/dist/adapters/terminal/overlay.js +0 -25
  60. package/dist/adapters/terminal/readiness.js +0 -11
  61. package/dist/adapters/terminal/surface.js +0 -135
  62. package/library/actions/terminal/perps/_venue.mjs +0 -242
  63. package/library/actions/terminal/perps/assert_orders.mjs +0 -54
  64. package/library/actions/terminal/perps/assert_positions.mjs +0 -40
  65. package/library/actions/terminal/perps/read_orders.mjs +0 -26
  66. package/library/actions/terminal/perps/read_positions.mjs +0 -25
  67. package/library/actions/terminal/perps/read_snapshot.mjs +0 -40
  68. package/library/actions/terminal/perps/revoke_agent.mjs +0 -58
  69. package/library/actions/terminal/perps/teardown_state.mjs +0 -104
  70. package/library/actions/terminal/ui/navigate.mjs +0 -31
  71. package/library/actions/terminal/wallet/_signature-log.mjs +0 -56
@@ -1,6 +1,6 @@
1
- // Resolve the Web Terminal slot runtime: ports, runtime paths, browser state and
2
- // wallet-fixture accounts. Key material is only ever returned as a viem account
3
- // object; callers must never log or persist it.
1
+ // Resolve the web-dapp slot runtime: the venue policy, ports, runtime paths,
2
+ // browser state and wallet-fixture accounts. Key material is only ever
3
+ // returned as a viem account object; callers must never log or persist it.
4
4
 
5
5
  import { realpathSync } from 'node:fs';
6
6
  import { readFile, writeFile } from 'node:fs/promises';
@@ -11,6 +11,9 @@ import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
11
11
 
12
12
  import { recipeRuntimeDir } from '@farmslot/recipe-cli/harness';
13
13
  import { walletFixturePath } from '../../harness-exports.mjs';
14
+ import { POLICY_ENV, webDappAdapterId, webDappPolicy } from '../../../../adapters/web-dapp/lib/policy.mjs';
15
+
16
+ export { POLICY_ENV, webDappAdapterId, webDappPolicy };
14
17
 
15
18
  export const SIGNER_MODES = Object.freeze(['extension', 'injected']);
16
19
  export const DEFAULT_ACCOUNT = 'dev1';
@@ -26,12 +29,13 @@ export function canonicalPath(target) {
26
29
  }
27
30
  }
28
31
 
29
- export function terminalRuntimeDir(projectRoot) {
30
- return path.join(canonicalPath(projectRoot), recipeRuntimeDir(), 'terminal');
32
+ // <checkout>/<runtime>/<adapter id>, e.g. temp/recipe/runtime/terminal.
33
+ export function webDappRuntimeDir(projectRoot) {
34
+ return path.join(canonicalPath(projectRoot), recipeRuntimeDir(), webDappPolicy().adapterId);
31
35
  }
32
36
 
33
- export function terminalRuntimePath(projectRoot, ...segments) {
34
- return path.join(terminalRuntimeDir(projectRoot), ...segments);
37
+ export function webDappRuntimePath(projectRoot, ...segments) {
38
+ return path.join(webDappRuntimeDir(projectRoot), ...segments);
35
39
  }
36
40
 
37
41
  function portFrom(raw, label) {
@@ -53,7 +57,7 @@ export function appPort(input = {}, env = process.env) {
53
57
  portFrom(env.WATCHER_PORT, 'WATCHER_PORT');
54
58
  if (!port) {
55
59
  throw new Error(
56
- 'terminal adapter requires the slot dev-server port.\n' +
60
+ `${webDappPolicy().adapterId} adapter requires the slot dev-server port.\n` +
57
61
  'Next: pass --watcher-port <port> (Farmslot: {{port}}) or set TERMINAL_APP_PORT.',
58
62
  );
59
63
  }
@@ -71,7 +75,7 @@ export function cdpPort(input = {}, env = process.env) {
71
75
  portFrom(env.CDP_PORT, 'CDP_PORT');
72
76
  if (!port) {
73
77
  throw new Error(
74
- 'terminal adapter requires a per-slot browser CDP port.\n' +
78
+ `${webDappPolicy().adapterId} adapter requires a per-slot browser CDP port.\n` +
75
79
  'Next: pass --cdp-port <port> (Farmslot: {{cdp_port}}).',
76
80
  );
77
81
  }
@@ -92,7 +96,7 @@ export async function writePrivateJson(file, value) {
92
96
  }
93
97
 
94
98
  export async function readBrowserState(projectRoot) {
95
- return readJsonFile(terminalRuntimePath(projectRoot, 'browser.json'));
99
+ return readJsonFile(webDappRuntimePath(projectRoot, 'browser.json'));
96
100
  }
97
101
 
98
102
  export function resolveSigner(raw) {
@@ -123,7 +127,7 @@ export async function loadWalletFixture(projectRoot, env = process.env) {
123
127
  if (!fixture) {
124
128
  throw new Error(
125
129
  `wallet fixture not found at ${file}.\n` +
126
- 'Next: mm-harness install --adapter terminal --target <checkout> with RECIPE_WALLET_FIXTURE set, or copy the fixture there (0600).',
130
+ `Next: mm-harness install --adapter ${webDappPolicy().adapterId} --target <checkout> with RECIPE_WALLET_FIXTURE set, or copy the fixture there (0600).`,
127
131
  );
128
132
  }
129
133
  if (!Array.isArray(fixture.accounts) || fixture.accounts.length === 0) {
@@ -195,7 +199,7 @@ export async function runAdapter(callback) {
195
199
  const output = await callback(input);
196
200
  await writeFile(input.outputPath, `${JSON.stringify(output, null, 2)}\n`);
197
201
  } catch (error) {
198
- process.stderr.write(`[terminal] ${input.action} failed: ${error?.stack ?? error}\n`);
202
+ process.stderr.write(`[${webDappAdapterId()}] ${input.action} failed: ${error?.stack ?? error}\n`);
199
203
  process.exitCode = 1;
200
204
  }
201
205
  }
@@ -0,0 +1,24 @@
1
+ // Navigate the app tab to an explicit app path, or a product page the venue
2
+ // policy names (the Terminal's order/<MARKET>, portfolio, home), and wait for
3
+ // the document to be ready.
4
+
5
+ import { appOrigin, isDirectRun, runAdapter, webDappPolicy } from '../platform/runtime.mjs';
6
+ import { withAppPage } from '../platform/page.mjs';
7
+
8
+ export function pathFor(node = {}, policy = webDappPolicy()) {
9
+ if (typeof node.path === 'string' && node.path.startsWith('/')) return node.path;
10
+ return policy.pagePath(node);
11
+ }
12
+
13
+ export async function navigate(input) {
14
+ const node = input.node ?? {};
15
+ const url = `${appOrigin(input)}${pathFor(node)}`;
16
+ return withAppPage({ ...input, node: { ...node, surface: 'app' } }, async (page) => {
17
+ await page.navigate(url, Number(node.timeout_ms ?? 120000));
18
+ await page.waitForDocumentReady({ expectedUrl: url, timeoutMs: Number(node.timeout_ms ?? 120000) });
19
+ if (node.settle_ms) await new Promise((resolve) => setTimeout(resolve, Number(node.settle_ms)));
20
+ return { action: input.action, url, page: node.page ?? 'order', market: node.market ?? null };
21
+ });
22
+ }
23
+
24
+ if (isDirectRun(import.meta.url)) runAdapter((input) => navigate(input));
@@ -0,0 +1,32 @@
1
+ // The wallet request log: where the wallet host writes it, and what the venue
2
+ // forbids in it. Reading, windowing and asserting the log are
3
+ // @farmslot/adapter-web/dapp's; the venue's rules come from its policy
4
+ // (`signatureLog`, the Terminal's L1 and mainnet rules).
5
+
6
+ import { webDappPolicy, webDappRuntimePath } from '../platform/runtime.mjs';
7
+
8
+ export function signatureLog(projectRoot) {
9
+ return {
10
+ logFile: webDappRuntimePath(projectRoot, 'wallet-requests.jsonl'),
11
+ cursorFile: webDappRuntimePath(projectRoot, 'wallet-requests.cursor.json'),
12
+ };
13
+ }
14
+
15
+ // What the venue forbids in the log (a SignaturePolicy), e.g. the Terminal's L1 and mainnet rules.
16
+ export function signaturePolicy() {
17
+ return webDappPolicy().signatureLog ?? {};
18
+ }
19
+
20
+ // The id the actions report their evidence under, e.g. terminal-wallet-request-log.
21
+ export function evidenceId(suffix) {
22
+ return `${webDappPolicy().adapterId}-${suffix}`;
23
+ }
24
+
25
+ // Evidence goes to <artifacts>/<adapter id>-wallet/<node>-signature-log.json.
26
+ export function logArtifactTarget(input) {
27
+ return {
28
+ artifactsDir: input.context?.artifactsDir,
29
+ nodeId: input.context?.nodeId ?? input.action,
30
+ folder: evidenceId('wallet'),
31
+ };
32
+ }
@@ -6,12 +6,12 @@
6
6
  import { awaitSignatureLog, writeLogArtifact } from '@farmslot/adapter-web/dapp';
7
7
 
8
8
  import { isDirectRun, runAdapter } from '../platform/runtime.mjs';
9
- import { TERMINAL_SIGNATURE_POLICY, logArtifactTarget, signatureLog } from './_signature-log.mjs';
9
+ import { evidenceId, logArtifactTarget, signatureLog, signaturePolicy } from './_signature-log.mjs';
10
10
 
11
11
  export async function assertSignatures(input) {
12
12
  const node = input.node ?? {};
13
13
  // Entries arrive asynchronously from the wallet host; timeout_ms allows a short settle.
14
- const { window, result } = await awaitSignatureLog(signatureLog(input.context?.projectRoot), node, TERMINAL_SIGNATURE_POLICY);
14
+ const { window, result } = await awaitSignatureLog(signatureLog(input.context?.projectRoot), node, signaturePolicy());
15
15
  const artifacts = await writeLogArtifact(logArtifactTarget(input), {
16
16
  cursor: window.cursor,
17
17
  total: window.total,
@@ -24,13 +24,13 @@ export async function assertSignatures(input) {
24
24
  }
25
25
  return {
26
26
  action: input.action,
27
- source: 'terminal-wallet-request-log',
27
+ source: evidenceId('wallet-request-log'),
28
28
  cursor: window.cursor,
29
29
  count: window.entries.length,
30
30
  summary: result.summary,
31
31
  entries: window.entries,
32
32
  artifacts,
33
- proofPath: 'terminal-wallet-request-log',
33
+ proofPath: evidenceId('wallet-request-log'),
34
34
  };
35
35
  }
36
36
 
@@ -1,7 +1,7 @@
1
1
  // List the wallet-fixture account names and addresses available to the slot
2
2
  // browser, marking the one the running browser uses. Addresses only.
3
3
 
4
- import { isDirectRun, loadWalletFixture, readBrowserState, runAdapter, viemAccountFromEntry } from '../platform/runtime.mjs';
4
+ import { isDirectRun, loadWalletFixture, readBrowserState, runAdapter, viemAccountFromEntry, webDappPolicy } from '../platform/runtime.mjs';
5
5
 
6
6
  export async function listAccounts(input) {
7
7
  const projectRoot = input.context?.projectRoot;
@@ -20,7 +20,7 @@ export async function listAccounts(input) {
20
20
  accounts,
21
21
  count: accounts.length,
22
22
  redacted: true,
23
- proofPath: 'terminal-wallet-accounts',
23
+ proofPath: `${webDappPolicy().adapterId}-wallet-accounts`,
24
24
  };
25
25
  }
26
26
 
@@ -5,7 +5,7 @@
5
5
  import { resetWindow, summarize, windowSinceCursor, writeLogArtifact } from '@farmslot/adapter-web/dapp';
6
6
 
7
7
  import { isDirectRun, runAdapter } from '../platform/runtime.mjs';
8
- import { TERMINAL_SIGNATURE_POLICY, logArtifactTarget, signatureLog } from './_signature-log.mjs';
8
+ import { evidenceId, logArtifactTarget, signatureLog, signaturePolicy } from './_signature-log.mjs';
9
9
 
10
10
  export async function readSignatures(input) {
11
11
  const log = signatureLog(input.context?.projectRoot);
@@ -13,25 +13,25 @@ export async function readSignatures(input) {
13
13
  const { cursor, previousEntries } = await resetWindow(log);
14
14
  return {
15
15
  action: input.action,
16
- source: 'terminal-wallet-request-log',
16
+ source: evidenceId('wallet-request-log'),
17
17
  reset: true,
18
18
  cursor,
19
19
  previousEntries,
20
- proofPath: 'terminal-wallet-request-log',
20
+ proofPath: evidenceId('wallet-request-log'),
21
21
  };
22
22
  }
23
23
  const { cursor, entries, total } = await windowSinceCursor(log);
24
- const summary = summarize(entries, TERMINAL_SIGNATURE_POLICY);
24
+ const summary = summarize(entries, signaturePolicy());
25
25
  const artifacts = await writeLogArtifact(logArtifactTarget(input), { cursor, total, summary, entries });
26
26
  return {
27
27
  action: input.action,
28
- source: 'terminal-wallet-request-log',
28
+ source: evidenceId('wallet-request-log'),
29
29
  cursor,
30
30
  count: entries.length,
31
31
  summary,
32
32
  entries,
33
33
  artifacts,
34
- proofPath: 'terminal-wallet-request-log',
34
+ proofPath: evidenceId('wallet-request-log'),
35
35
  };
36
36
  }
37
37