@deeeed/metamask-harness 0.70.1 → 0.72.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 +25 -0
- package/adapters/extension/console-tail.mjs +38 -6
- package/adapters/manifest.json +128 -0
- package/adapters/terminal/cleanup.mjs +68 -0
- package/adapters/terminal/inject.mjs +74 -0
- package/adapters/terminal/launch.mjs +628 -0
- package/adapters/terminal/lib/cdp-client.mjs +84 -0
- package/adapters/terminal/lib/display.mjs +115 -0
- package/adapters/terminal/lib/hud.mjs +148 -0
- package/adapters/terminal/lib/mainnet-guard.mjs +177 -0
- package/adapters/terminal/lib/origin.mjs +30 -0
- package/adapters/terminal/lib/page-script.mjs +246 -0
- package/adapters/terminal/lib/processes.mjs +187 -0
- package/adapters/terminal/lib/readiness.mjs +274 -0
- package/adapters/terminal/lib/strict-wallet.mjs +138 -0
- package/adapters/terminal/stop.mjs +37 -0
- package/adapters/terminal/verify.mjs +48 -0
- package/adapters/terminal/wallet-host.mjs +703 -0
- package/dist/adapters/console-capture.js +122 -0
- package/dist/adapters/extension/console-capture.js +22 -85
- package/dist/adapters/mobile/verify.js +8 -3
- package/dist/adapters/surface.js +3 -1
- package/dist/adapters/terminal/console-capture.js +46 -0
- package/dist/adapters/terminal/stop.js +19 -0
- package/dist/adapters/terminal/surface.js +104 -0
- package/dist/adapters.js +27 -4
- package/dist/cli.js +2 -2
- package/dist/command-contract.js +12 -4
- package/dist/commands/check.js +1 -1
- package/dist/commands/config.js +1 -1
- package/dist/commands/doctor.js +24 -1
- package/dist/commands/domain.js +1 -1
- package/dist/commands/farmslot-ready.js +2 -0
- package/dist/commands/help.js +2 -2
- package/dist/commands/launch/index.js +97 -2
- package/dist/commands/manifest.js +3 -3
- package/dist/commands/recipe-advice.js +1 -1
- package/dist/commands/review.js +1 -1
- package/dist/commands/run-engine.js +1 -1
- package/dist/commands/shared.js +1 -1
- package/dist/doctor.js +3 -0
- package/dist/harness.js +17 -11
- package/dist/manifest.js +5 -0
- package/dist/mm-harness-cli.js +34 -20
- package/dist/paths.js +2 -2
- package/dist/recipe-security.js +12 -3
- package/dist/review/knowledge.js +1 -1
- package/dist/run-diagnostics.js +150 -33
- package/dist/runner.js +1 -1
- package/dist/runtime-context.js +3 -3
- package/docs/CONTRIBUTING.md +1 -1
- package/docs/cli-contract.md +163 -0
- package/library/actions/shared/console-allowlist-add.mjs +137 -0
- package/library/actions/shared/console-collector.mjs +230 -0
- package/library/actions/shared/console-findings.mjs +511 -0
- package/library/actions/terminal/app/assert_no_console_errors.mjs +119 -0
- package/library/actions/terminal/app/launch.mjs +45 -0
- package/library/actions/terminal/perps/_venue.mjs +242 -0
- package/library/actions/terminal/perps/assert_orders.mjs +54 -0
- package/library/actions/terminal/perps/assert_positions.mjs +40 -0
- package/library/actions/terminal/perps/read_orders.mjs +26 -0
- package/library/actions/terminal/perps/read_positions.mjs +25 -0
- package/library/actions/terminal/perps/read_snapshot.mjs +40 -0
- package/library/actions/terminal/perps/revoke_agent.mjs +58 -0
- package/library/actions/terminal/perps/teardown_state.mjs +104 -0
- package/library/actions/terminal/platform/hud.mjs +71 -0
- package/library/actions/terminal/platform/page.mjs +247 -0
- package/library/actions/terminal/platform/runtime.mjs +200 -0
- package/library/actions/terminal/ui/navigate.mjs +31 -0
- package/library/actions/terminal/wallet/_signature-log.mjs +177 -0
- package/library/actions/terminal/wallet/assert_signatures.mjs +43 -0
- package/library/actions/terminal/wallet/list_accounts.mjs +27 -0
- package/library/actions/terminal/wallet/read_signatures.mjs +37 -0
- package/library/manifests/terminal.action-manifest.json +1786 -0
- package/package.json +2 -1
package/dist/commands/help.js
CHANGED
|
@@ -4,9 +4,9 @@ import { color } from "../cli-color.js";
|
|
|
4
4
|
import { detectAdapter } from "../harness.js";
|
|
5
5
|
import { optionString, parseArgs, targetPath } from "./parse-args.js";
|
|
6
6
|
import { handleHelpReview } from "./review.js";
|
|
7
|
-
const UNSCOPED_NEXT = "cd into a MetaMask checkout or pass --adapter <mobile|extension|core>";
|
|
7
|
+
const UNSCOPED_NEXT = "cd into a MetaMask checkout or pass --adapter <mobile|extension|core|terminal>";
|
|
8
8
|
function validHelpLine(value) {
|
|
9
|
-
return typeof value === "string" || Boolean(value && typeof value.text === "string" && Array.isArray(value.adapters) && value.adapters.length > 0 && value.adapters.every((adapter) => ["mobile", "extension", "core"].includes(adapter)));
|
|
9
|
+
return typeof value === "string" || Boolean(value && typeof value.text === "string" && Array.isArray(value.adapters) && value.adapters.length > 0 && value.adapters.every((adapter) => ["mobile", "extension", "core", "terminal"].includes(adapter)));
|
|
10
10
|
}
|
|
11
11
|
function scopedSections(topic, adapter) {
|
|
12
12
|
const select = (lines) => lines.flatMap((line) => typeof line === "string" ? [line] : line.adapters.includes(adapter) ? [line.text] : []);
|
|
@@ -59,7 +59,10 @@ const LAUNCH_BOOLEANS = /* @__PURE__ */ new Set([
|
|
|
59
59
|
"runway",
|
|
60
60
|
"clearMetro",
|
|
61
61
|
"json",
|
|
62
|
-
"jsonStream"
|
|
62
|
+
"jsonStream",
|
|
63
|
+
"freshProfile",
|
|
64
|
+
"headless",
|
|
65
|
+
"headful"
|
|
63
66
|
]);
|
|
64
67
|
const DEFAULT_EXTENSION_DAPP_URL = "https://metamask.github.io/test-dapp/";
|
|
65
68
|
function metroLaunchEvidence(adapter, target) {
|
|
@@ -117,6 +120,83 @@ async function handleLaunch(argv) {
|
|
|
117
120
|
restoreStdout();
|
|
118
121
|
}
|
|
119
122
|
}
|
|
123
|
+
const TERMINAL_ONLY_LAUNCH_OPTIONS = Object.freeze({
|
|
124
|
+
signer: "--signer",
|
|
125
|
+
account: "--account",
|
|
126
|
+
freshProfile: "--fresh-profile",
|
|
127
|
+
headless: "--headless",
|
|
128
|
+
headful: "--headful",
|
|
129
|
+
slowMo: "--slow-mo",
|
|
130
|
+
network: "--network",
|
|
131
|
+
mainnetConfirmation: "--mainnet-confirmation"
|
|
132
|
+
});
|
|
133
|
+
function terminalOnlyLaunchFlags(options) {
|
|
134
|
+
return Object.entries(TERMINAL_ONLY_LAUNCH_OPTIONS).filter(([key]) => options[key] !== void 0 && options[key] !== false).map(([, name]) => name);
|
|
135
|
+
}
|
|
136
|
+
function parseTerminalLauncherOutput(output) {
|
|
137
|
+
const text = output.trim();
|
|
138
|
+
if (!text) return { status: "fail", error: "the terminal launcher printed no summary" };
|
|
139
|
+
try {
|
|
140
|
+
return JSON.parse(text);
|
|
141
|
+
} catch {
|
|
142
|
+
const last = text.split("\n").filter((line) => line.trim()).pop() ?? "";
|
|
143
|
+
try {
|
|
144
|
+
return JSON.parse(last);
|
|
145
|
+
} catch {
|
|
146
|
+
return { status: "fail", error: `the terminal launcher printed no JSON summary: ${last.slice(0, 200)}` };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function launchTerminal(options, target, jsonOutput, stream) {
|
|
151
|
+
const cdpPort = str(options, "cdpPort") ?? process.env.RECIPE_CDP_PORT ?? process.env.CDP_PORT;
|
|
152
|
+
const appPort = str(options, "watcherPort") ?? process.env.TERMINAL_APP_PORT ?? process.env.RECIPE_WATCHER_PORT ?? process.env.WATCHER_PORT;
|
|
153
|
+
if (!cdpPort || !appPort) {
|
|
154
|
+
return launchUsage(
|
|
155
|
+
jsonOutput,
|
|
156
|
+
stream,
|
|
157
|
+
"terminal launch needs the slot browser CDP port and the slot dev-server port.",
|
|
158
|
+
"mm-harness launch --adapter terminal --cdp-port <port> --watcher-port <app port>"
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
const args = [
|
|
162
|
+
path.join(runnerDir, "adapters", "terminal", "launch.mjs"),
|
|
163
|
+
"--target",
|
|
164
|
+
target,
|
|
165
|
+
"--cdp-port",
|
|
166
|
+
cdpPort,
|
|
167
|
+
"--app-port",
|
|
168
|
+
appPort,
|
|
169
|
+
"--signer",
|
|
170
|
+
str(options, "signer") ?? process.env.TERMINAL_SIGNER ?? "extension",
|
|
171
|
+
"--account",
|
|
172
|
+
str(options, "account") ?? process.env.TERMINAL_ACCOUNT ?? "dev1",
|
|
173
|
+
"--json"
|
|
174
|
+
];
|
|
175
|
+
if (flag(options, "freshProfile")) args.push("--fresh-profile");
|
|
176
|
+
if (flag(options, "headless")) args.push("--headless");
|
|
177
|
+
if (flag(options, "headful")) args.push("--headful");
|
|
178
|
+
const slowMo = str(options, "slowMo");
|
|
179
|
+
if (slowMo) args.push("--slow-mo", slowMo);
|
|
180
|
+
const network = str(options, "network");
|
|
181
|
+
if (network) args.push("--network", network);
|
|
182
|
+
const mainnetConfirmation = str(options, "mainnetConfirmation");
|
|
183
|
+
if (mainnetConfirmation) args.push("--mainnet-confirmation", mainnetConfirmation);
|
|
184
|
+
stream.phase("launch", { adapter: "terminal", cdpPort, appPort });
|
|
185
|
+
let output = "";
|
|
186
|
+
let status = 0;
|
|
187
|
+
try {
|
|
188
|
+
output = execFileSync(process.execPath, args, { encoding: "utf8", stdio: ["ignore", "pipe", "inherit"] });
|
|
189
|
+
} catch (error) {
|
|
190
|
+
status = 1;
|
|
191
|
+
output = String(error.stdout ?? "");
|
|
192
|
+
}
|
|
193
|
+
const result = parseTerminalLauncherOutput(output);
|
|
194
|
+
if (jsonOutput) console.log(JSON.stringify({ schemaVersion: 1, command: "launch", adapter: "terminal", target, ...result }, null, 2));
|
|
195
|
+
else if (result.status === "pass") console.log(`\u2713 terminal browser ${result.reused ? "reused" : "started"} on CDP ${result.cdpPort} (${result.signer}, ${result.account?.name})`);
|
|
196
|
+
else console.error(`\u2717 terminal launch failed: ${result.error ?? "unknown error"}`);
|
|
197
|
+
stream.complete(result.status === "pass" ? "pass" : "fail", status);
|
|
198
|
+
return result.status === "pass" ? 0 : 1;
|
|
199
|
+
}
|
|
120
200
|
async function handleLaunchLocked(argv, stream) {
|
|
121
201
|
const { positional, options } = parseFlags(argv, LAUNCH_BOOLEANS);
|
|
122
202
|
const json = flag(options, "json");
|
|
@@ -139,6 +219,18 @@ async function handleLaunchLocked(argv, stream) {
|
|
|
139
219
|
if (adapter === "core") {
|
|
140
220
|
return launchUsage(jsonOutput, stream, "core is headless; there is nothing to launch.", "mm-harness verify");
|
|
141
221
|
}
|
|
222
|
+
if (adapter === "terminal") {
|
|
223
|
+
return launchTerminal(options, target, jsonOutput, stream);
|
|
224
|
+
}
|
|
225
|
+
const terminalOnly = terminalOnlyLaunchFlags(options);
|
|
226
|
+
if (terminalOnly.length > 0) {
|
|
227
|
+
return launchUsage(
|
|
228
|
+
jsonOutput,
|
|
229
|
+
stream,
|
|
230
|
+
`${terminalOnly.join(", ")} apply only to --adapter terminal; ${adapter} does not read them.`,
|
|
231
|
+
"drop the terminal flags, or pass --adapter terminal"
|
|
232
|
+
);
|
|
233
|
+
}
|
|
142
234
|
if (adapter === "mobile" && !mobileTarget) {
|
|
143
235
|
return launchUsage(
|
|
144
236
|
jsonOutput,
|
|
@@ -943,5 +1035,8 @@ ${failure.originalError}` : "") + `
|
|
|
943
1035
|
return failure.exitCode;
|
|
944
1036
|
}
|
|
945
1037
|
export {
|
|
946
|
-
|
|
1038
|
+
TERMINAL_ONLY_LAUNCH_OPTIONS,
|
|
1039
|
+
handleLaunch,
|
|
1040
|
+
parseTerminalLauncherOutput,
|
|
1041
|
+
terminalOnlyLaunchFlags
|
|
947
1042
|
};
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import { metaMaskActionExecutionCapabilities } from "../recipe-security.js";
|
|
19
19
|
import { closest } from "../command-contract.js";
|
|
20
20
|
const OFFICIAL_ACTIONS = new Set(OFFICIAL_RECIPE_ACTIONS);
|
|
21
|
-
const ACTION_MATRIX_ADAPTERS = ["mobile", "extension", "core"];
|
|
21
|
+
const ACTION_MATRIX_ADAPTERS = ["mobile", "extension", "core", "terminal"];
|
|
22
22
|
function actionLibraryContextArgs(librarySources) {
|
|
23
23
|
return (librarySources ?? []).filter((source) => source.name !== "metamask").map((source) => {
|
|
24
24
|
const entry = source.name ? `${source.name}=${source.root}` : source.root;
|
|
@@ -309,9 +309,9 @@ function renderHumanActionMatrix(actions) {
|
|
|
309
309
|
return [
|
|
310
310
|
out("bold", "action capability matrix"),
|
|
311
311
|
out("comment", "Inspect one: mm-harness actions --matrix --action <name> --json"),
|
|
312
|
-
`${"action capability".padEnd(width)} mobile extension core`,
|
|
312
|
+
`${"action capability".padEnd(width)} mobile extension core terminal`,
|
|
313
313
|
...actions.map(
|
|
314
|
-
(action) => `${action.name.padEnd(width)} ${cell(action.support.mobile, 6)} ${cell(action.support.extension, 9)} ${cell(action.support.core, 4)}`
|
|
314
|
+
(action) => `${action.name.padEnd(width)} ${cell(action.support.mobile, 6)} ${cell(action.support.extension, 9)} ${cell(action.support.core, 4)} ${cell(action.support.terminal, 8)}`
|
|
315
315
|
)
|
|
316
316
|
].join("\n");
|
|
317
317
|
}
|
|
@@ -29,7 +29,7 @@ async function runRecipeAdvice(options, mode) {
|
|
|
29
29
|
const adapter = optionString(options, "adapter");
|
|
30
30
|
const output = optionString(options, "output");
|
|
31
31
|
const evidence = optionString(options, "evidence");
|
|
32
|
-
if (mode === "review" && !recipe || !task || !["mobile", "extension", "core"].includes(adapter ?? "")) {
|
|
32
|
+
if (mode === "review" && !recipe || !task || !["mobile", "extension", "core", "terminal"].includes(adapter ?? "")) {
|
|
33
33
|
throw usageError("Use recipe-quality plan --task <task.json>, or advise --recipe <recipe.json> --task <TASK.md>, with --adapter <adapter> [--advisor <provider>].");
|
|
34
34
|
}
|
|
35
35
|
if (mode === "plan" && (recipe || evidence || optionString(options, "params"))) throw usageError("Planning runs before a recipe exists. Next: use advise to review a draft or evidence.");
|
package/dist/commands/review.js
CHANGED
|
@@ -27,7 +27,7 @@ function harnessVersion() {
|
|
|
27
27
|
function adapterFromOptions(options, target) {
|
|
28
28
|
const raw = optionString(options, "adapter") ?? optionString(options, "platform");
|
|
29
29
|
if (raw !== void 0) {
|
|
30
|
-
if (raw !== "mobile" && raw !== "extension" && raw !== "core") throw usageError(`--adapter must be mobile, extension, or
|
|
30
|
+
if (raw !== "mobile" && raw !== "extension" && raw !== "core" && raw !== "terminal") throw usageError(`--adapter must be mobile, extension, core, or terminal (got ${raw}).`);
|
|
31
31
|
return raw;
|
|
32
32
|
}
|
|
33
33
|
return detectAdapter(target) ?? "unscoped";
|
|
@@ -150,7 +150,7 @@ async function runRecipe(adapter, recipe, artifactsDir, projectRoot, actionManif
|
|
|
150
150
|
if (executionError !== void 0) throw executionError;
|
|
151
151
|
if (recordingError !== void 0) throw recordingError;
|
|
152
152
|
if (!result) throw new Error("Recipe execution returned no result.");
|
|
153
|
-
const finalized = finishRunDiagnostics(diagnosticBaseline, result);
|
|
153
|
+
const finalized = await finishRunDiagnostics(diagnosticBaseline, result);
|
|
154
154
|
persistRunEffects(
|
|
155
155
|
finalized.summaryPath,
|
|
156
156
|
finalized.artifactManifestPath,
|
package/dist/commands/shared.js
CHANGED
|
@@ -59,7 +59,7 @@ function flag(options, key) {
|
|
|
59
59
|
function targetOf(options) {
|
|
60
60
|
return path.resolve(str(options, "target") ?? process.cwd());
|
|
61
61
|
}
|
|
62
|
-
const ADAPTER_TOKENS = ["mobile", "extension", "core"];
|
|
62
|
+
const ADAPTER_TOKENS = ["mobile", "extension", "core", "terminal"];
|
|
63
63
|
function resolveAdapter(options, target, hint) {
|
|
64
64
|
const platform = str(options, "platform");
|
|
65
65
|
const explicit = str(options, "adapter") ?? (platform === "ios" || platform === "android" ? "mobile" : platform);
|
package/dist/doctor.js
CHANGED
|
@@ -45,6 +45,9 @@ function compatibilityMode(adapter, target) {
|
|
|
45
45
|
if (adapter === "core") {
|
|
46
46
|
return fs.existsSync(path.join(target, "packages/perps-controller/src/index.ts")) ? "headless controller (no bridge)" : "unsupported/no bridge";
|
|
47
47
|
}
|
|
48
|
+
if (adapter === "terminal") {
|
|
49
|
+
return fs.existsSync(path.join(target, "src/features/perpetuals")) ? "slot browser over CDP (website; no product bridge)" : "unsupported/no bridge";
|
|
50
|
+
}
|
|
48
51
|
if (adapter === "mobile") {
|
|
49
52
|
if (shape.injectedHarness && shape.agenticService) return "runner bridge with injected app bridge";
|
|
50
53
|
if (shape.agenticService) return "runner bridge with app bridge";
|
package/dist/harness.js
CHANGED
|
@@ -7,11 +7,11 @@ import { resolveExtensionSlotPorts } from "./adapters/slot-ports.js";
|
|
|
7
7
|
import { recipeHarnessPath, recipeRuntimeDir, runnerDir } from "./paths.js";
|
|
8
8
|
import { colorHumanMessage } from "./cli-color.js";
|
|
9
9
|
const HARNESS_ACTIONS = ["install", "verify", "cleanup"];
|
|
10
|
-
const ADAPTERS = ["mobile", "extension", "core"];
|
|
10
|
+
const ADAPTERS = ["mobile", "extension", "core", "terminal"];
|
|
11
11
|
function harnessUsage() {
|
|
12
12
|
console.error(`mm-harness \u2014 install and validate the MetaMask recipe runtime in a checkout.
|
|
13
13
|
|
|
14
|
-
Run it from inside a MetaMask checkout; the platform (mobile | extension | core)
|
|
14
|
+
Run it from inside a MetaMask checkout; the platform (mobile | extension | core | terminal)
|
|
15
15
|
is auto-detected from the repo. Pass --platform only to override.
|
|
16
16
|
|
|
17
17
|
Commands (one copy-pasteable example each):
|
|
@@ -23,7 +23,7 @@ Commands (one copy-pasteable example each):
|
|
|
23
23
|
mm-harness cleanup
|
|
24
24
|
|
|
25
25
|
Options:
|
|
26
|
-
--platform <mobile|extension|core> Override auto-detection (alias: --adapter).
|
|
26
|
+
--platform <mobile|extension|core|terminal> Override auto-detection (alias: --adapter).
|
|
27
27
|
--target <repo> Checkout to operate on (default: current dir).
|
|
28
28
|
--json Machine-readable summary for agents/scripts.
|
|
29
29
|
-- <args> Forward the rest verbatim to the underlying
|
|
@@ -67,7 +67,7 @@ function shellQuote(value) {
|
|
|
67
67
|
return /^[A-Za-z0-9_./:=@+-]+$/u.test(value) ? value : `'${value.replace(/'/gu, `'\\''`)}'`;
|
|
68
68
|
}
|
|
69
69
|
function isAdapter(value) {
|
|
70
|
-
return value === "mobile" || value === "extension" || value === "core";
|
|
70
|
+
return value === "mobile" || value === "extension" || value === "core" || value === "terminal";
|
|
71
71
|
}
|
|
72
72
|
function parseHarnessArgs(args) {
|
|
73
73
|
const forward = [];
|
|
@@ -125,7 +125,7 @@ function parseHarnessArgs(args) {
|
|
|
125
125
|
}
|
|
126
126
|
return { adapter, json, quiet, forward };
|
|
127
127
|
}
|
|
128
|
-
const ADAPTER_DETECT_NEXT = "cd into a MetaMask checkout or pass --target <path>, or force it with --adapter <mobile|extension|core>";
|
|
128
|
+
const ADAPTER_DETECT_NEXT = "cd into a MetaMask checkout or pass --target <path>, or force it with --adapter <mobile|extension|core|terminal>";
|
|
129
129
|
function detectAdapter(target) {
|
|
130
130
|
let remote = "";
|
|
131
131
|
try {
|
|
@@ -149,6 +149,7 @@ function detectAdapter(target) {
|
|
|
149
149
|
if (exists("development/skills-sync.ts") || isDir("ui") && isDir("app/scripts")) return "extension";
|
|
150
150
|
if (exists("scripts/skills-sync.mts") || isDir("ios") && isDir("android") && isDir("app/core")) return "mobile";
|
|
151
151
|
if (isDir("packages/perps-controller") && exists("yarn.lock")) return "core";
|
|
152
|
+
if (remote.includes("va-mmcx-terminal") || isDir("src/features/perpetuals") && (exists("next.config.ts") || exists("next.config.mjs") || exists("next.config.js"))) return "terminal";
|
|
152
153
|
return void 0;
|
|
153
154
|
}
|
|
154
155
|
function resolveRuntimeContextPath(target) {
|
|
@@ -227,29 +228,34 @@ function isExecutable(file) {
|
|
|
227
228
|
const INJECT_CANDIDATES = {
|
|
228
229
|
mobile: { entry: "adapters/mobile/inject.sh", fallback: "scripts/inject-mobile-harness.sh" },
|
|
229
230
|
extension: { entry: "adapters/extension/inject.mjs", fallback: "scripts/inject-extension-harness.mjs" },
|
|
230
|
-
core: { entry: "adapters/core/inject.sh", fallback: "scripts/inject-core-harness.sh" }
|
|
231
|
+
core: { entry: "adapters/core/inject.sh", fallback: "scripts/inject-core-harness.sh" },
|
|
232
|
+
terminal: { entry: "adapters/terminal/inject.mjs", fallback: "adapters/terminal/inject.mjs" }
|
|
231
233
|
};
|
|
232
234
|
const CLEANUP_CANDIDATES = {
|
|
233
235
|
mobile: { entry: "adapters/mobile/cleanup.sh", fallback: "scripts/cleanup-mobile-harness.sh" },
|
|
234
236
|
extension: { entry: "adapters/extension/cleanup.mjs", fallback: "scripts/cleanup-extension-harness.mjs" },
|
|
235
|
-
core: { entry: "adapters/core/cleanup.sh", fallback: "scripts/cleanup-core-harness.sh" }
|
|
237
|
+
core: { entry: "adapters/core/cleanup.sh", fallback: "scripts/cleanup-core-harness.sh" },
|
|
238
|
+
terminal: { entry: "adapters/terminal/cleanup.mjs", fallback: "adapters/terminal/cleanup.mjs" }
|
|
236
239
|
};
|
|
237
240
|
function resolveHarnessDispatch(adapter, action, target) {
|
|
238
241
|
if (action === "install") {
|
|
239
242
|
const { entry, fallback } = INJECT_CANDIDATES[adapter];
|
|
240
|
-
if (adapter === "extension") {
|
|
243
|
+
if (adapter === "extension" || adapter === "terminal") {
|
|
241
244
|
return { command: process.execPath, prefixArgs: [resolveEntry(runnerDir, [entry, fallback], "file")] };
|
|
242
245
|
}
|
|
243
246
|
return { command: resolveEntry(runnerDir, [entry, fallback], "file"), prefixArgs: [] };
|
|
244
247
|
}
|
|
245
248
|
if (action === "cleanup") {
|
|
246
249
|
const { entry, fallback } = CLEANUP_CANDIDATES[adapter];
|
|
247
|
-
const base = installedRunnerSource(target, adapter) ?? runnerDir;
|
|
248
|
-
if (adapter === "extension") {
|
|
250
|
+
const base = adapter === "terminal" ? runnerDir : installedRunnerSource(target, adapter) ?? runnerDir;
|
|
251
|
+
if (adapter === "extension" || adapter === "terminal") {
|
|
249
252
|
return { command: process.execPath, prefixArgs: [resolveEntry(base, [entry, fallback], "file")] };
|
|
250
253
|
}
|
|
251
254
|
return { command: resolveEntry(base, [entry, fallback], "file"), prefixArgs: [] };
|
|
252
255
|
}
|
|
256
|
+
if (adapter === "terminal" && action === "verify") {
|
|
257
|
+
return { command: process.execPath, prefixArgs: [path.join(runnerDir, "adapters", "terminal", "verify.mjs")] };
|
|
258
|
+
}
|
|
253
259
|
if (adapter === "core" && action === "verify") {
|
|
254
260
|
const delegate = path.join(recipeHarnessPath(target, "core"), "runner", "bin", "mm-harness");
|
|
255
261
|
if (!isExecutable(delegate)) {
|
|
@@ -282,7 +288,7 @@ async function handleHarness(argv) {
|
|
|
282
288
|
if (quiet) {
|
|
283
289
|
return 2;
|
|
284
290
|
} else if (json) {
|
|
285
|
-
const detectError = adapter ? { code: "UNSUPPORTED_PLATFORM", message: `unsupported platform: ${adapter}`, userAction: "pass --adapter <mobile|extension|core> to specify a supported adapter" } : { code: "ADAPTER_DETECTION_FAILED", message: `could not detect the MetaMask repo type for ${target}`, userAction: ADAPTER_DETECT_NEXT };
|
|
291
|
+
const detectError = adapter ? { code: "UNSUPPORTED_PLATFORM", message: `unsupported platform: ${adapter}`, userAction: "pass --adapter <mobile|extension|core|terminal> to specify a supported adapter" } : { code: "ADAPTER_DETECTION_FAILED", message: `could not detect the MetaMask repo type for ${target}`, userAction: ADAPTER_DETECT_NEXT };
|
|
286
292
|
console.log(harnessSummary(harnessAction, void 0, target, "fail", 2, false, detectError));
|
|
287
293
|
} else {
|
|
288
294
|
harnessUsage();
|
package/dist/manifest.js
CHANGED
|
@@ -11,10 +11,14 @@ function loadMetaMaskExtensionActionManifest() {
|
|
|
11
11
|
function loadMetaMaskCoreActionManifest() {
|
|
12
12
|
return asActionManifest(readJson(manifestPath("core")));
|
|
13
13
|
}
|
|
14
|
+
function loadMetaMaskTerminalActionManifest() {
|
|
15
|
+
return asActionManifest(readJson(manifestPath("terminal")));
|
|
16
|
+
}
|
|
14
17
|
function loadActionManifest(adapter, overridePath) {
|
|
15
18
|
if (overridePath) return asActionManifest(readJson(path.resolve(overridePath)));
|
|
16
19
|
if (adapter === "mobile") return loadMetaMaskMobileActionManifest();
|
|
17
20
|
if (adapter === "core") return loadMetaMaskCoreActionManifest();
|
|
21
|
+
if (adapter === "terminal") return loadMetaMaskTerminalActionManifest();
|
|
18
22
|
return loadMetaMaskExtensionActionManifest();
|
|
19
23
|
}
|
|
20
24
|
async function resolveActionManifest(adapter, overridePath, librarySources, taskActionRoot) {
|
|
@@ -165,6 +169,7 @@ export {
|
|
|
165
169
|
loadMetaMaskCoreActionManifest,
|
|
166
170
|
loadMetaMaskExtensionActionManifest,
|
|
167
171
|
loadMetaMaskMobileActionManifest,
|
|
172
|
+
loadMetaMaskTerminalActionManifest,
|
|
168
173
|
resolveActionManifest,
|
|
169
174
|
validateManifest
|
|
170
175
|
};
|
package/dist/mm-harness-cli.js
CHANGED
|
@@ -32,7 +32,7 @@ const REAL = [
|
|
|
32
32
|
|
|
33
33
|
Loads the complete recipe guide shipped with this harness.
|
|
34
34
|
|
|
35
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
35
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
36
36
|
--target <path> Checkout path (default: cwd)
|
|
37
37
|
--json Load the same guide as structured agent context
|
|
38
38
|
|
|
@@ -121,7 +121,7 @@ Example:
|
|
|
121
121
|
helpText: `mm-harness config <list|path|get <key>|set <key> <value>|unset <key>> [--json]
|
|
122
122
|
|
|
123
123
|
Stored outside every repo in ~/.mm-harness/config.json (override: MM_HARNESS_CONFIG).
|
|
124
|
-
Keys: libraries.<name> (team library checkout), references.<mobile|extension|core>
|
|
124
|
+
Keys: libraries.<name> (team library checkout), references.<mobile|extension|core|terminal>
|
|
125
125
|
(the checkout used as the parity reference), advisor.enabled (true/false),
|
|
126
126
|
advisor.provider, advisor.model, advisor.stages (plan,draft,evidence). Advisor
|
|
127
127
|
settings contain no credentials and default to disabled with planning only.
|
|
@@ -267,7 +267,7 @@ Example:
|
|
|
267
267
|
refuses with the numbered choice when that is ambiguous.
|
|
268
268
|
|
|
269
269
|
--target <path> Checkout path (default: cwd)
|
|
270
|
-
--platform <mobile|extension|core> Force the platform (auto-detected inside a checkout)
|
|
270
|
+
--platform <mobile|extension|core|terminal> Force the platform (auto-detected inside a checkout)
|
|
271
271
|
--mobile-platform <ios|android> Mobile target when status cannot decide it
|
|
272
272
|
--clear-metro Mobile only: clear Metro's transform cache in the launch step
|
|
273
273
|
--artifacts-dir <dir> Where sandbox.json and the per-step reports land
|
|
@@ -378,10 +378,10 @@ Materialize:
|
|
|
378
378
|
|
|
379
379
|
query Search names, categories, fields, and descriptions (typo-tolerant)
|
|
380
380
|
--action <name> Describe one action; fuzzy-resolves like call (short or full name)
|
|
381
|
-
--matrix Compare action availability across Mobile, Extension, and
|
|
381
|
+
--matrix Compare action availability across Mobile, Extension, Core, and Terminal
|
|
382
382
|
--categories List compact action categories and counts
|
|
383
383
|
--category <name> List only one category (for example ui, wallet, or perps)
|
|
384
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
384
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
385
385
|
--target <path> Checkout path (default: cwd)
|
|
386
386
|
--raw Dump raw action registry JSON
|
|
387
387
|
--json Machine-readable output
|
|
@@ -409,7 +409,7 @@ Example:
|
|
|
409
409
|
core headless \u2014 no dev server to stop (teaching error)
|
|
410
410
|
|
|
411
411
|
--port <port> Metro/webpack port override; Extension CDP remains checkout-context scoped
|
|
412
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
412
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
413
413
|
--target <path> Checkout path (default: cwd)
|
|
414
414
|
--json Machine-readable output
|
|
415
415
|
|
|
@@ -437,7 +437,7 @@ Example:
|
|
|
437
437
|
--arg k=v Action field value (repeatable; equivalent to key=value shorthand)
|
|
438
438
|
--device <udid|serial|name> Mobile only: target this device (sets IOS_SIMULATOR / ADB_SERIAL and updates agentic-runtime.json). Without it, >1 connected mobile device fails fast and lists them. Do not shut down other devices to force selection.
|
|
439
439
|
--cdp-port <port> Extension only: bind the action to this live browser runtime.
|
|
440
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
440
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
441
441
|
--target <path> Checkout path (default: cwd)
|
|
442
442
|
--artifacts-dir <dir> Where to write evidence (default: temp dir)
|
|
443
443
|
--action-manifest <path> Override the action manifest
|
|
@@ -477,7 +477,7 @@ Discovery:
|
|
|
477
477
|
|
|
478
478
|
Common overrides:
|
|
479
479
|
--device <udid|serial|name> Mobile only: target this device (sets IOS_SIMULATOR / ADB_SERIAL and updates agentic-runtime.json). Without it, >1 connected mobile device fails fast and lists them. Do not shut down other devices to force selection.
|
|
480
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
480
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
481
481
|
--platform <ios|android> Mobile platform preference; use --adapter for the product adapter
|
|
482
482
|
--target <path> Checkout path (default: cwd)
|
|
483
483
|
--artifacts-dir <dir> Override evidence output (default: active task/artifacts, otherwise a checkout-local temp/recipe/runs/<run>)
|
|
@@ -490,7 +490,7 @@ Common overrides:
|
|
|
490
490
|
--json Machine-readable output
|
|
491
491
|
--json-stream Line-flushed JSONL progress + terminal event
|
|
492
492
|
--record-video=full-run Record a video of the run
|
|
493
|
-
--hud <auto|show|hide> Recipe HUD policy (auto shows normal Mobile recipes; hide is explicit)
|
|
493
|
+
--hud <auto|show|hide> Recipe HUD policy (auto shows normal Mobile recipes and a headful terminal browser; hide is explicit)
|
|
494
494
|
|
|
495
495
|
Advanced integrations:
|
|
496
496
|
runtime: --cdp-port, --watcher-port/--metro-port, --runtime-dir, --slot,
|
|
@@ -537,7 +537,7 @@ Example:
|
|
|
537
537
|
--cdp-port <port> Extension CDP port for the liveness probe (env: CDP_PORT / RECIPE_CDP_PORT)
|
|
538
538
|
--device <udid|serial|name> Mobile only: target this device (env: IOS_SIMULATOR / ADB_SERIAL). doctor reports the connected devices; it never gates on ambiguity.
|
|
539
539
|
--all-devices Mobile only: show every connected device instead of the slot-scoped target
|
|
540
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
540
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
541
541
|
--target <path> Checkout path (default: cwd)
|
|
542
542
|
--runtime-dir <dir> Runtime dir containing agentic-runtime.json (relative to target)
|
|
543
543
|
--json Machine-readable output (incompatible with --print-ready)
|
|
@@ -559,7 +559,7 @@ Example:
|
|
|
559
559
|
when available. Does not launch an app or run a recipe.
|
|
560
560
|
|
|
561
561
|
--target <path> Checkout path (default: cwd)
|
|
562
|
-
--adapter <mobile|extension|core> Adapter label (auto-detected when possible)
|
|
562
|
+
--adapter <mobile|extension|core|terminal> Adapter label (auto-detected when possible)
|
|
563
563
|
--base <ref> Diff base (default: PR base, then remote HEAD, then repo fallback)
|
|
564
564
|
--profile <fast|full> Validation depth (default: fast)
|
|
565
565
|
--fix Fix changed files, then validate them
|
|
@@ -596,11 +596,11 @@ Example:
|
|
|
596
596
|
Optional advice:
|
|
597
597
|
advisor-status --json
|
|
598
598
|
Resolve saved settings and overrides without reading tasks or calling a model.
|
|
599
|
-
plan --task <task.json> --adapter <mobile|extension|core> --advisor typesafe
|
|
599
|
+
plan --task <task.json> --adapter <mobile|extension|core|terminal> --advisor typesafe
|
|
600
600
|
Assess each acceptance criterion before a recipe exists. Task JSON contains
|
|
601
601
|
acceptanceCriteria: ["criterion", "..."] (1\u201320 entries), with optional title/description.
|
|
602
602
|
Returns known candidate refs for reuse/composition, or an explicit discovery gap.
|
|
603
|
-
advise --recipe <recipe.json> --task <TASK.md> --adapter <mobile|extension|core>
|
|
603
|
+
advise --recipe <recipe.json> --task <TASK.md> --adapter <mobile|extension|core|terminal>
|
|
604
604
|
--advisor <provider|off> Override saved policy for this task (currently: typesafe)
|
|
605
605
|
--advisor-model <model> Override the provider default model or alias
|
|
606
606
|
--advisor-stages <csv> Select plan,draft,evidence (saved/default: plan)
|
|
@@ -635,7 +635,7 @@ Example:
|
|
|
635
635
|
provisioning path only: artifact cache + simulator create + simctl install.
|
|
636
636
|
JavaScript dependencies and Metro remain dispatch-time launch concerns.
|
|
637
637
|
|
|
638
|
-
--adapter <mobile|extension|core> Target adapter (mobile supported; extension/core teach)
|
|
638
|
+
--adapter <mobile|extension|core|terminal> Target adapter (mobile supported; extension/core/terminal teach)
|
|
639
639
|
--target <path> Slot checkout path (default: cwd)
|
|
640
640
|
--platform <ios> Platform (default ios)
|
|
641
641
|
--simulator <name|udid> Override agentic-runtime.json simulator (alias: --device)
|
|
@@ -669,7 +669,7 @@ Example:
|
|
|
669
669
|
artifact cache + simulator create + simctl install. JavaScript dependencies
|
|
670
670
|
and Metro remain dispatch-time launch concerns.
|
|
671
671
|
|
|
672
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
672
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
673
673
|
--target <path> Checkout path (default: cwd)
|
|
674
674
|
--runway Thin mobile Runway artifact install instead of overlay install
|
|
675
675
|
--platform <ios> Runway platform (default ios)
|
|
@@ -698,7 +698,7 @@ Example:
|
|
|
698
698
|
Extension live checks infer the checkout CDP port from runtime context,
|
|
699
699
|
pool, or slot suffix when --cdp-port is omitted.
|
|
700
700
|
|
|
701
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
701
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
702
702
|
--target <path> Checkout path (default: cwd)
|
|
703
703
|
--json Machine-readable output
|
|
704
704
|
|
|
@@ -714,7 +714,7 @@ Example:
|
|
|
714
714
|
|
|
715
715
|
Remove the installed overlay and restore the checkout.
|
|
716
716
|
|
|
717
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
717
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
718
718
|
--target <path> Checkout path (default: cwd)
|
|
719
719
|
|
|
720
720
|
Example:
|
|
@@ -730,6 +730,7 @@ Example:
|
|
|
730
730
|
Launch the app \u2014 quick relaunch by default; --build for a full native/webpack build.
|
|
731
731
|
Mobile: target is MANDATORY (ios | android). Extension: no target (--fullscreen default;
|
|
732
732
|
--sidepanel to override). core is headless (teaching error \u2014 use verify/run).
|
|
733
|
+
Terminal: starts or reuses the slot browser (visible by default) against the slot dev server.
|
|
733
734
|
Extension quick launch REUSES a healthy live runtime (reload in place, no rebuild);
|
|
734
735
|
--build is the escape hatch that always clean-builds + relaunches a fresh runtime.
|
|
735
736
|
|
|
@@ -750,7 +751,19 @@ Example:
|
|
|
750
751
|
--device <udid|name> Target simulator/device (env: IOS_SIMULATOR / ADB_SERIAL)
|
|
751
752
|
--cdp-port <port> Extension CDP port (env: CDP_PORT / RECIPE_CDP_PORT)
|
|
752
753
|
--watcher-port <port> Metro/webpack port (env: WATCHER_PORT / METRO_PORT)
|
|
753
|
-
--
|
|
754
|
+
--signer <extension|injected> Terminal: MetaMask extension (default) or the injected test wallet
|
|
755
|
+
--account <name> Terminal: wallet-fixture account (default dev1)
|
|
756
|
+
--fresh-profile Terminal: start from a new browser profile
|
|
757
|
+
--headless Terminal: hide the browser (env: TERMINAL_HEADLESS=1); default is a
|
|
758
|
+
visible window placed per slot (--headful is accepted as the default)
|
|
759
|
+
--slow-mo <ms> Terminal: pause before each UI action (env: TERMINAL_SLOW_MO; default 0)
|
|
760
|
+
--network <testnet|mainnet> Terminal: venue the slot dev server serves (default testnet)
|
|
761
|
+
--mainnet-confirmation <REAL_FUNDS> Terminal: required with --network mainnet (real funds)
|
|
762
|
+
Terminal flags are rejected for other adapters. The terminal launch
|
|
763
|
+
refuses unless the farm next dev server on --watcher-port forces
|
|
764
|
+
Hyperliquid testnet, or --network mainnet --mainnet-confirmation REAL_FUNDS
|
|
765
|
+
is passed (a recipe launch node carries network/mainnet_confirmation).
|
|
766
|
+
--adapter <mobile|extension|terminal> Target adapter (auto-detected inside a checkout)
|
|
754
767
|
--target <path> Checkout path (default: cwd)
|
|
755
768
|
--json Machine-readable summary (recovered[] / mutations[] / phase)
|
|
756
769
|
--json-stream Line-flushed JSONL progress + terminal event
|
|
@@ -777,7 +790,7 @@ Example:
|
|
|
777
790
|
--source <label> Log source per adapter \u2014 mobile: metro|app;
|
|
778
791
|
extension: extension|dapp|webpack|watcher|rebuild.
|
|
779
792
|
Core is headless (teaching error).
|
|
780
|
-
--adapter <mobile|extension|core> Target adapter (auto-detected inside a checkout)
|
|
793
|
+
--adapter <mobile|extension|core|terminal> Target adapter (auto-detected inside a checkout)
|
|
781
794
|
--target <path> Checkout path (default: cwd)
|
|
782
795
|
--json Machine-readable output
|
|
783
796
|
|
|
@@ -981,6 +994,7 @@ function adapterFromRuntimeContext(ctx) {
|
|
|
981
994
|
if (raw === "mobile" || raw === "ios" || raw === "android") return "mobile";
|
|
982
995
|
if (raw === "extension" || raw === "chrome-extension") return "extension";
|
|
983
996
|
if (raw === "core") return "core";
|
|
997
|
+
if (raw === "terminal") return "terminal";
|
|
984
998
|
return void 0;
|
|
985
999
|
}
|
|
986
1000
|
function detectedSlotLine(out) {
|
|
@@ -1010,7 +1024,7 @@ function groupedHelp() {
|
|
|
1010
1024
|
const out = (style, text) => color(style, text, { stream: process.stdout });
|
|
1011
1025
|
const lines = [];
|
|
1012
1026
|
lines.push(`${out("bold", "mm-harness")} \u2014 one front door for the MetaMask recipe loop: launch the app, prove behavior, manage the runtime overlay.`);
|
|
1013
|
-
lines.push("Run it from inside a MetaMask checkout; the platform (mobile | extension | core) is auto-detected.");
|
|
1027
|
+
lines.push("Run it from inside a MetaMask checkout; the platform (mobile | extension | core | terminal) is auto-detected.");
|
|
1014
1028
|
lines.push(`Grammar: ${out("cmd", "mm-harness <command> [target] [flags]")} (target is a positional: ios | android; flags add agent depth; --json is the agent contract)`);
|
|
1015
1029
|
if (process.env.MM_HARNESS_BIN) {
|
|
1016
1030
|
lines.push("");
|
package/dist/paths.js
CHANGED
|
@@ -88,8 +88,8 @@ function isProtocolRoot(candidate) {
|
|
|
88
88
|
return fs.existsSync(path.join(candidate, "packages/recipe-harness/package.json")) && fs.existsSync(path.join(candidate, "packages/protocol/package.json"));
|
|
89
89
|
}
|
|
90
90
|
function assertAdapter(adapter) {
|
|
91
|
-
if (adapter !== "mobile" && adapter !== "extension" && adapter !== "core") {
|
|
92
|
-
throw new Error("Adapter must be mobile, extension, or
|
|
91
|
+
if (adapter !== "mobile" && adapter !== "extension" && adapter !== "core" && adapter !== "terminal") {
|
|
92
|
+
throw new Error("Adapter must be mobile, extension, core, or terminal.");
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
function manifestPath(adapter) {
|
package/dist/recipe-security.js
CHANGED
|
@@ -27,7 +27,12 @@ const READ_ONLY_CUSTOM_ACTIONS = /* @__PURE__ */ new Set([
|
|
|
27
27
|
// Collector reads are host-only; starting capture remains arbitrary-code
|
|
28
28
|
// because it spawns an HTTP listener.
|
|
29
29
|
"metamask.analytics.read_events",
|
|
30
|
-
"metamask.analytics.assert_events"
|
|
30
|
+
"metamask.analytics.assert_events",
|
|
31
|
+
// Terminal wallet request log reads.
|
|
32
|
+
"metamask.wallet.read_signatures",
|
|
33
|
+
"metamask.wallet.assert_signatures",
|
|
34
|
+
// Terminal console capture read.
|
|
35
|
+
"metamask.app.assert_no_console_errors"
|
|
31
36
|
]);
|
|
32
37
|
const APP_MUTATION_CUSTOM_ACTIONS = /* @__PURE__ */ new Set([
|
|
33
38
|
"metamask.assets.verify_sorting",
|
|
@@ -72,7 +77,10 @@ const APP_MUTATION_CUSTOM_ACTIONS = /* @__PURE__ */ new Set([
|
|
|
72
77
|
"metamask.perps.start_state",
|
|
73
78
|
"metamask.perps.teardown_state",
|
|
74
79
|
// Consent changes wallet state and is therefore an app mutation.
|
|
75
|
-
"metamask.analytics.set_consent"
|
|
80
|
+
"metamask.analytics.set_consent",
|
|
81
|
+
// Terminal slot browser lifecycle and venue agent revocation.
|
|
82
|
+
"metamask.app.launch",
|
|
83
|
+
"metamask.perps.revoke_agent"
|
|
76
84
|
]);
|
|
77
85
|
const EXTERNAL_MUTATION_CUSTOM_ACTIONS = /* @__PURE__ */ new Set([
|
|
78
86
|
"metamask.swap_bridge.submit_transaction",
|
|
@@ -82,7 +90,8 @@ const EXTERNAL_MUTATION_CUSTOM_ACTIONS = /* @__PURE__ */ new Set([
|
|
|
82
90
|
"metamask.perps.close_visible_position",
|
|
83
91
|
"metamask.perps.edit_margin",
|
|
84
92
|
"metamask.perps.edit_order",
|
|
85
|
-
"metamask.perps.update_position_tpsl"
|
|
93
|
+
"metamask.perps.update_position_tpsl",
|
|
94
|
+
"metamask.perps.revoke_agent"
|
|
86
95
|
]);
|
|
87
96
|
function metaMaskActionExecutionCapabilities(action) {
|
|
88
97
|
const capabilities = [];
|
package/dist/review/knowledge.js
CHANGED
|
@@ -4,7 +4,7 @@ import os from "node:os";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { detectAdapter } from "../harness.js";
|
|
6
6
|
import { usageError } from "../commands/parse-args.js";
|
|
7
|
-
const REVIEW_ADAPTERS = ["mobile", "extension", "core"];
|
|
7
|
+
const REVIEW_ADAPTERS = ["mobile", "extension", "core", "terminal"];
|
|
8
8
|
const ADVISOR_STAGES = ["plan", "draft", "evidence"];
|
|
9
9
|
function parseAdvisorSettings(value) {
|
|
10
10
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw usageError("advisor settings must be an object. Next: use mm-harness config set advisor.enabled false.");
|