@deeeed/metamask-harness 0.2.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.
- package/CHANGELOG.md +161 -0
- package/README.md +140 -0
- package/bin/mm-harness +99 -0
- package/docs/CHEATSHEET.md +61 -0
- package/docs/CLI-SPEC.md +915 -0
- package/docs/MENTAL-MODEL.md +295 -0
- package/docs/architecture.md +367 -0
- package/docs/extension-runtime-commands.md +60 -0
- package/docs/harness-cli.md +43 -0
- package/docs/live-adapter-contract.md +188 -0
- package/docs/package-boundaries.md +47 -0
- package/docs/perps-flow-catalog.md +235 -0
- package/docs/recipe-libraries.md +95 -0
- package/docs/runtime-file-conventions.md +36 -0
- package/library/actions/core/perps/_controller.mjs +727 -0
- package/library/actions/core/perps/assert_orders.mjs +53 -0
- package/library/actions/core/perps/assert_positions.mjs +52 -0
- package/library/actions/core/perps/close_orders.mjs +97 -0
- package/library/actions/core/perps/close_positions.mjs +118 -0
- package/library/actions/core/perps/ensure_orders.mjs +40 -0
- package/library/actions/core/perps/ensure_positions.mjs +37 -0
- package/library/actions/core/perps/place_order.mjs +201 -0
- package/library/actions/core/perps/read_account.mjs +30 -0
- package/library/actions/core/perps/read_orders.mjs +27 -0
- package/library/actions/core/perps/read_positions.mjs +27 -0
- package/library/actions/core/perps/start_state.mjs +92 -0
- package/library/actions/core/perps/teardown_state.mjs +86 -0
- package/library/actions/extension/perps/assert_orders.mjs +11 -0
- package/library/actions/extension/perps/assert_positions.mjs +11 -0
- package/library/actions/extension/perps/close_orders.mjs +8 -0
- package/library/actions/extension/perps/close_positions.mjs +8 -0
- package/library/actions/extension/perps/ensure_orders.mjs +4 -0
- package/library/actions/extension/perps/ensure_positions.mjs +4 -0
- package/library/actions/extension/perps/perps.mjs +730 -0
- package/library/actions/extension/perps/place_order.mjs +7 -0
- package/library/actions/extension/perps/read_orders.mjs +4 -0
- package/library/actions/extension/perps/read_positions.mjs +3 -0
- package/library/actions/extension/platform/cdp.mjs +541 -0
- package/library/actions/extension/ui/navigate.mjs +44 -0
- package/library/actions/extension/wallet/ensure_unlocked.mjs +36 -0
- package/library/actions/extension/wallet/read_state.mjs +27 -0
- package/library/actions/extension/wallet/select_account.mjs +48 -0
- package/library/actions/extension/wallet/setup.mjs +35 -0
- package/library/actions/mobile/app-overlay/app/dev-tools/AgenticService/AgentStepHud.tsx.patch +185 -0
- package/library/actions/mobile/app-overlay/app/dev-tools/AgenticService/AgenticService.ts.patch +1662 -0
- package/library/actions/mobile/bridge-runtime/cdp-bridge.cjs +686 -0
- package/library/actions/mobile/bridge-runtime/lib/cdp-eval.cjs +110 -0
- package/library/actions/mobile/bridge-runtime/lib/config.cjs +39 -0
- package/library/actions/mobile/bridge-runtime/lib/issue-capture.cjs +446 -0
- package/library/actions/mobile/bridge-runtime/lib/target-discovery.cjs +204 -0
- package/library/actions/mobile/bridge-runtime/lib/ws-client.cjs +108 -0
- package/library/actions/mobile/bridge-runtime/setup-wallet.sh +442 -0
- package/library/actions/mobile/perps/assert_orders.mjs +11 -0
- package/library/actions/mobile/perps/assert_positions.mjs +11 -0
- package/library/actions/mobile/perps/close_orders.mjs +8 -0
- package/library/actions/mobile/perps/close_positions.mjs +8 -0
- package/library/actions/mobile/perps/ensure_orders.mjs +4 -0
- package/library/actions/mobile/perps/ensure_positions.mjs +4 -0
- package/library/actions/mobile/perps/perps.mjs +709 -0
- package/library/actions/mobile/perps/place_order.mjs +7 -0
- package/library/actions/mobile/perps/read_orders.mjs +4 -0
- package/library/actions/mobile/perps/read_positions.mjs +3 -0
- package/library/actions/mobile/platform/bridge.mjs +283 -0
- package/library/actions/mobile/ui/navigate.mjs +38 -0
- package/library/actions/mobile/wallet/ensure_unlocked.mjs +107 -0
- package/library/actions/mobile/wallet/home.mjs +35 -0
- package/library/actions/mobile/wallet/read_state.mjs +40 -0
- package/library/actions/mobile/wallet/select_account.mjs +48 -0
- package/library/actions/mobile/wallet/setup.mjs +220 -0
- package/library/flows/perps.flows.json +64 -0
- package/library/library.json +7 -0
- package/library/manifests/core.action-manifest.json +1282 -0
- package/library/manifests/extension.action-manifest.json +1749 -0
- package/library/manifests/mobile.action-manifest.json +1753 -0
- package/library/recipes/action-validation.extension.recipe.json +417 -0
- package/library/recipes/action-validation.mobile.recipe.json +422 -0
- package/library/recipes/order-lifecycle.core.recipe.json +78 -0
- package/library/recipes/perps-lifecycle.recipe.json +194 -0
- package/library/recipes/read-markets.core.recipe.json +38 -0
- package/library/recipes/smoke.extension.recipe.json +31 -0
- package/library/recipes/smoke.mobile.recipe.json +31 -0
- package/library/recipes/trading-lifecycle.core.recipe.json +76 -0
- package/orchestration/compat-overlays/README.md +19 -0
- package/orchestration/compat-overlays/mobile/README.md +13 -0
- package/orchestration/compat-overlays/mobile/rn81-message-event-source.patch +42 -0
- package/orchestration/core/cleanup.sh +37 -0
- package/orchestration/core/inject.sh +154 -0
- package/orchestration/doctor.mjs +72 -0
- package/orchestration/extension/cleanup.mjs +60 -0
- package/orchestration/extension/console-tail.mjs +228 -0
- package/orchestration/extension/ensure-browser.sh +416 -0
- package/orchestration/extension/ensure-ready.ts +185 -0
- package/orchestration/extension/extension-id.ts +107 -0
- package/orchestration/extension/inject.mjs +266 -0
- package/orchestration/extension/launch-browser.cjs +216 -0
- package/orchestration/extension/launch.sh +175 -0
- package/orchestration/extension/live.sh +320 -0
- package/orchestration/extension/pin-remote-flags.cjs +45 -0
- package/orchestration/extension/readiness.mjs +414 -0
- package/orchestration/extension/refresh-build.sh +190 -0
- package/orchestration/extension/runtime-decision.ts +445 -0
- package/orchestration/extension/runtime.ts +407 -0
- package/orchestration/extension/seed-fixture.sh +177 -0
- package/orchestration/extension/sidepanel-toggle.sh +291 -0
- package/orchestration/extension/snapshot-dist.sh +84 -0
- package/orchestration/extension/start-watch.sh +339 -0
- package/orchestration/extension/wallet-fixture-state.cjs +1086 -0
- package/orchestration/lib/activate-repo-node.sh +144 -0
- package/orchestration/lib/cli-color.mjs +84 -0
- package/orchestration/lib/cli-commands.mjs +243 -0
- package/orchestration/lib/cli-home.mjs +354 -0
- package/orchestration/lib/cli-ux.sh +252 -0
- package/orchestration/lib/cli-version.mjs +123 -0
- package/orchestration/lib/ensure-runner-deps.sh +56 -0
- package/orchestration/lib/harness-path.sh +55 -0
- package/orchestration/lib/hash-helpers.sh +44 -0
- package/orchestration/lib/json-field.sh +23 -0
- package/orchestration/lib/log-tui.mjs +304 -0
- package/orchestration/lib/open-debug.mjs +317 -0
- package/orchestration/lib/path-defaults.json +4 -0
- package/orchestration/lib/progress.mjs +107 -0
- package/orchestration/lib/recipe-paths.mjs +26 -0
- package/orchestration/lib/resolve-farmslot-ports.sh +144 -0
- package/orchestration/manifest.json +358 -0
- package/orchestration/mobile/cleanup.sh +192 -0
- package/orchestration/mobile/deps-markers.ts +21 -0
- package/orchestration/mobile/inject.sh +681 -0
- package/orchestration/mobile/launch.sh +137 -0
- package/orchestration/mobile/live.sh +125 -0
- package/orchestration/mobile/runtime-decision.ts +292 -0
- package/orchestration/porcelain/metamask-recipe +99 -0
- package/orchestration/porcelain/mm-recipe +1591 -0
- package/orchestration/porcelain/mme-recipe +1181 -0
- package/package.json +59 -0
- package/runner/extension/verify.sh +511 -0
- package/runner/mobile/verify.sh +501 -0
- package/runner/src/adapters.ts +601 -0
- package/runner/src/cli.ts +1820 -0
- package/runner/src/commands/debug.ts +44 -0
- package/runner/src/commands/fixtures.ts +99 -0
- package/runner/src/commands/launch.ts +397 -0
- package/runner/src/commands/logs.ts +60 -0
- package/runner/src/commands/shared.ts +138 -0
- package/runner/src/completions-cache.ts +86 -0
- package/runner/src/doctor.ts +203 -0
- package/runner/src/harness.ts +516 -0
- package/runner/src/heal-bounds.ts +179 -0
- package/runner/src/index.ts +6 -0
- package/runner/src/live-adapter-contract.ts +274 -0
- package/runner/src/manifest.ts +47 -0
- package/runner/src/mm-harness-cli.ts +488 -0
- package/runner/src/paths.ts +198 -0
- package/runner/src/recording-target.ts +147 -0
- package/runner/src/run-recording.ts +329 -0
- package/runner/src/runner.ts +108 -0
- package/runner/src/types.ts +57 -0
- package/scripts/completions.sh +125 -0
- package/scripts/install-completions.sh +62 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { isDirectRun, resolveNetwork, runAdapter } from './_controller.mjs';
|
|
2
|
+
import { ensureOrders } from './ensure_orders.mjs';
|
|
3
|
+
import { ensurePositions } from './ensure_positions.mjs';
|
|
4
|
+
|
|
5
|
+
// core Headless composite that converges the POSITION and ORDER baselines for the
|
|
6
|
+
// selected market(s) on HyperLiquid testnet before the proof window. Mirrors the
|
|
7
|
+
// extension perps-domain-dispatcher start_state semantics but SKIPS every
|
|
8
|
+
// navigation/page/HUD step — headless core has no UI surface.
|
|
9
|
+
//
|
|
10
|
+
// Params (extension schema, testnet-default): profile, market(s)/symbol(s),
|
|
11
|
+
// positions{state,...}, orders{state,...}, network. The UI-only `page`/`hud`
|
|
12
|
+
// fields are accepted by the schema but intentionally ignored here.
|
|
13
|
+
//
|
|
14
|
+
// A baseline block converges to its `state` by composing the ensure_* helpers; a
|
|
15
|
+
// block set to `false` (or omitted) skips that domain. Position convergence runs
|
|
16
|
+
// first (closing a position also clears its TP/SL orders), then order
|
|
17
|
+
// convergence, so the final order baseline is authoritative.
|
|
18
|
+
|
|
19
|
+
const BASELINE_KEYS = [
|
|
20
|
+
'market',
|
|
21
|
+
'symbol',
|
|
22
|
+
'markets',
|
|
23
|
+
'symbols',
|
|
24
|
+
'selector',
|
|
25
|
+
'mode',
|
|
26
|
+
'side',
|
|
27
|
+
'network',
|
|
28
|
+
'account',
|
|
29
|
+
'account_name',
|
|
30
|
+
'timeout_ms',
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Build an ensure_* input from the composite node plus a domain baseline block.
|
|
35
|
+
* Selection/account/network fields flow from the top-level node; per-domain
|
|
36
|
+
* fields (state, notional, leverage, offset_pct, ...) come from the block.
|
|
37
|
+
*
|
|
38
|
+
* @param input - The composite adapter input.
|
|
39
|
+
* @param action - The target ensure action name (for trace fidelity).
|
|
40
|
+
* @param baseline - The domain baseline object (positions/orders).
|
|
41
|
+
*/
|
|
42
|
+
function ensureInput(input, action, baseline) {
|
|
43
|
+
const inherited = {};
|
|
44
|
+
for (const key of BASELINE_KEYS) {
|
|
45
|
+
if (input.node?.[key] !== undefined) inherited[key] = input.node[key];
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
...input,
|
|
49
|
+
action,
|
|
50
|
+
node: { ...inherited, ...baseline, action },
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Normalize a baseline block. `false` or absent → skip; an object → use as-is.
|
|
56
|
+
* Anything else is a recipe error.
|
|
57
|
+
*/
|
|
58
|
+
function normalizeBaseline(value, label) {
|
|
59
|
+
if (value === undefined || value === null || value === false) return null;
|
|
60
|
+
if (typeof value === 'object' && !Array.isArray(value)) return value;
|
|
61
|
+
throw new Error(`metamask.perps.start_state ${label} must be an object or false, got ${JSON.stringify(value)}.`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function startState(input) {
|
|
65
|
+
const network = resolveNetwork(input);
|
|
66
|
+
const positionsBaseline = normalizeBaseline(input.node?.positions, 'positions');
|
|
67
|
+
const ordersBaseline = normalizeBaseline(input.node?.orders, 'orders');
|
|
68
|
+
|
|
69
|
+
const result = {
|
|
70
|
+
action: input.action,
|
|
71
|
+
source: 'perps-controller-composite',
|
|
72
|
+
network,
|
|
73
|
+
profile: input.node?.profile ?? null,
|
|
74
|
+
converged: { positions: null, orders: null },
|
|
75
|
+
proofPath: 'perps-controller-start_state',
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
if (positionsBaseline) {
|
|
79
|
+
result.converged.positions = await ensurePositions(
|
|
80
|
+
ensureInput(input, 'metamask.perps.ensure_positions', positionsBaseline),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if (ordersBaseline) {
|
|
84
|
+
result.converged.orders = await ensureOrders(
|
|
85
|
+
ensureInput(input, 'metamask.perps.ensure_orders', ordersBaseline),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (isDirectRun(import.meta.url)) runAdapter(startState);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { isDirectRun, resolveNetwork, runAdapter } from './_controller.mjs';
|
|
2
|
+
import { ensureOrders } from './ensure_orders.mjs';
|
|
3
|
+
import { ensurePositions } from './ensure_positions.mjs';
|
|
4
|
+
|
|
5
|
+
// core Headless composite that restores the POSITION and ORDER baselines for the
|
|
6
|
+
// selected market(s) on HyperLiquid testnet after the proof window. Mirrors the
|
|
7
|
+
// extension perps-domain-dispatcher teardown_state semantics but SKIPS every
|
|
8
|
+
// navigation/page/HUD step — headless core has no UI surface.
|
|
9
|
+
//
|
|
10
|
+
// Params (extension schema, testnet-default): profile, market(s)/symbol(s),
|
|
11
|
+
// positions{state,...}, orders{state,...}, network. The UI-only `page`/`hud`
|
|
12
|
+
// fields are accepted by the schema but intentionally ignored here.
|
|
13
|
+
//
|
|
14
|
+
// Teardown defaults BOTH domains to state=none (leave the shared dev account
|
|
15
|
+
// FLAT) when a baseline block is omitted; pass a block explicitly to override, or
|
|
16
|
+
// `false` to skip a domain. Orders are canceled FIRST, then positions are closed,
|
|
17
|
+
// so resting orders never re-arm against a position mid-teardown.
|
|
18
|
+
|
|
19
|
+
const BASELINE_KEYS = [
|
|
20
|
+
'market',
|
|
21
|
+
'symbol',
|
|
22
|
+
'markets',
|
|
23
|
+
'symbols',
|
|
24
|
+
'selector',
|
|
25
|
+
'mode',
|
|
26
|
+
'side',
|
|
27
|
+
'network',
|
|
28
|
+
'account',
|
|
29
|
+
'account_name',
|
|
30
|
+
'timeout_ms',
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
function ensureInput(input, action, baseline) {
|
|
34
|
+
const inherited = {};
|
|
35
|
+
for (const key of BASELINE_KEYS) {
|
|
36
|
+
if (input.node?.[key] !== undefined) inherited[key] = input.node[key];
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
...input,
|
|
40
|
+
action,
|
|
41
|
+
node: { ...inherited, ...baseline, action },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Normalize a teardown baseline block.
|
|
47
|
+
* - `false` → skip the domain.
|
|
48
|
+
* - object → use as-is.
|
|
49
|
+
* - undefined/null → default to { state: 'none' } (restore to flat).
|
|
50
|
+
*/
|
|
51
|
+
function normalizeBaseline(value, label) {
|
|
52
|
+
if (value === false) return null;
|
|
53
|
+
if (value === undefined || value === null) return { state: 'none' };
|
|
54
|
+
if (typeof value === 'object' && !Array.isArray(value)) return value;
|
|
55
|
+
throw new Error(`metamask.perps.teardown_state ${label} must be an object or false, got ${JSON.stringify(value)}.`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function teardownState(input) {
|
|
59
|
+
const network = resolveNetwork(input);
|
|
60
|
+
const ordersBaseline = normalizeBaseline(input.node?.orders, 'orders');
|
|
61
|
+
const positionsBaseline = normalizeBaseline(input.node?.positions, 'positions');
|
|
62
|
+
|
|
63
|
+
const result = {
|
|
64
|
+
action: input.action,
|
|
65
|
+
source: 'perps-controller-composite',
|
|
66
|
+
network,
|
|
67
|
+
profile: input.node?.profile ?? null,
|
|
68
|
+
converged: { orders: null, positions: null },
|
|
69
|
+
proofPath: 'perps-controller-teardown_state',
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
if (ordersBaseline) {
|
|
73
|
+
result.converged.orders = await ensureOrders(
|
|
74
|
+
ensureInput(input, 'metamask.perps.ensure_orders', ordersBaseline),
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
if (positionsBaseline) {
|
|
78
|
+
result.converged.positions = await ensurePositions(
|
|
79
|
+
ensureInput(input, 'metamask.perps.ensure_positions', positionsBaseline),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (isDirectRun(import.meta.url)) runAdapter(teardownState);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { runAdapter } from '../platform/cdp.mjs';
|
|
2
|
+
import { assertOrders } from './perps.mjs';
|
|
3
|
+
|
|
4
|
+
function expectedOpen(input) {
|
|
5
|
+
const state = String(input.node?.state ?? input.node?.orders ?? 'open').toLowerCase();
|
|
6
|
+
if (state === 'open' || state === 'present') return true;
|
|
7
|
+
if (state === 'none' || state === 'closed' || state === 'absent') return false;
|
|
8
|
+
throw new Error(`metamask.perps.assert_orders received unsupported state: ${state}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
runAdapter((input) => assertOrders(input, expectedOpen(input)));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { runAdapter } from '../platform/cdp.mjs';
|
|
2
|
+
import { assertPositions } from './perps.mjs';
|
|
3
|
+
|
|
4
|
+
function expectedOpen(input) {
|
|
5
|
+
const state = String(input.node?.state ?? input.node?.position ?? 'open').toLowerCase();
|
|
6
|
+
if (state === 'open' || state === 'present') return true;
|
|
7
|
+
if (state === 'none' || state === 'closed' || state === 'absent') return false;
|
|
8
|
+
throw new Error(`metamask.perps.assert_positions received unsupported state: ${state}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
runAdapter((input) => assertPositions(input, expectedOpen(input)));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { runAdapter } from '../platform/cdp.mjs';
|
|
2
|
+
import { assertOrders, closeOrders } from './perps.mjs';
|
|
3
|
+
|
|
4
|
+
runAdapter(async (input) => {
|
|
5
|
+
const close = await closeOrders(input);
|
|
6
|
+
const assertion = await assertOrders(input, false);
|
|
7
|
+
return { ...assertion, close };
|
|
8
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { runAdapter } from '../platform/cdp.mjs';
|
|
2
|
+
import { assertPositions, closePositions } from './perps.mjs';
|
|
3
|
+
|
|
4
|
+
runAdapter(async (input) => {
|
|
5
|
+
const close = await closePositions(input);
|
|
6
|
+
const assertion = await assertPositions(input, false);
|
|
7
|
+
return { ...assertion, close };
|
|
8
|
+
});
|