@mozilla/firefox-devtools-mcp 0.9.5 → 0.9.7
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/README.md +9 -2
- package/dist/index.js +847 -129
- package/package.json +6 -6
- package/scripts/test-closed-window.js +216 -0
package/dist/index.js
CHANGED
|
@@ -164,9 +164,13 @@ var init_cli = __esm({
|
|
|
164
164
|
description: "Android app package name (default: org.mozilla.firefox). Use org.mozilla.fenix for Nightly.",
|
|
165
165
|
default: process.env.ANDROID_PACKAGE ?? "org.mozilla.firefox"
|
|
166
166
|
},
|
|
167
|
+
logFile: {
|
|
168
|
+
type: "string",
|
|
169
|
+
description: "Path to a file where MCP server logs will be written. Set DEBUG=* to also enable verbose debug logs."
|
|
170
|
+
},
|
|
167
171
|
enableScript: {
|
|
168
172
|
type: "boolean",
|
|
169
|
-
description: "Enable the
|
|
173
|
+
description: "Enable the script tools such as script evaluation and logpoints (Firefox 153+ required).",
|
|
170
174
|
default: (process.env.ENABLE_SCRIPT ?? "false") === "true"
|
|
171
175
|
},
|
|
172
176
|
enablePrivilegedContext: {
|
|
@@ -27224,12 +27228,12 @@ var require_dist = __commonJS({
|
|
|
27224
27228
|
throw new Error(`Unknown format "${name}"`);
|
|
27225
27229
|
return f;
|
|
27226
27230
|
};
|
|
27227
|
-
function addFormats(ajv, list,
|
|
27231
|
+
function addFormats(ajv, list, fs2, exportName) {
|
|
27228
27232
|
var _a2;
|
|
27229
27233
|
var _b;
|
|
27230
27234
|
(_a2 = (_b = ajv.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
27231
27235
|
for (const f of list)
|
|
27232
|
-
ajv.addFormat(f,
|
|
27236
|
+
ajv.addFormat(f, fs2[f]);
|
|
27233
27237
|
}
|
|
27234
27238
|
module.exports = exports = formatsPlugin;
|
|
27235
27239
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -28078,27 +28082,76 @@ var init_constants = __esm({
|
|
|
28078
28082
|
});
|
|
28079
28083
|
|
|
28080
28084
|
// src/utils/logger.ts
|
|
28081
|
-
|
|
28082
|
-
|
|
28085
|
+
import fs from "fs";
|
|
28086
|
+
function formatArgs(args2) {
|
|
28087
|
+
if (args2.length === 0) {
|
|
28088
|
+
return "";
|
|
28089
|
+
}
|
|
28090
|
+
return " " + args2.map((a) => {
|
|
28091
|
+
if (typeof a === "string") {
|
|
28092
|
+
return a;
|
|
28093
|
+
}
|
|
28094
|
+
try {
|
|
28095
|
+
return JSON.stringify(a);
|
|
28096
|
+
} catch {
|
|
28097
|
+
return String(a);
|
|
28098
|
+
}
|
|
28099
|
+
}).join(" ");
|
|
28083
28100
|
}
|
|
28084
|
-
function
|
|
28085
|
-
if (
|
|
28086
|
-
|
|
28087
|
-
|
|
28088
|
-
|
|
28101
|
+
function flushLogs(timeoutMs = 2e3) {
|
|
28102
|
+
if (!logStream) {
|
|
28103
|
+
return Promise.resolve();
|
|
28104
|
+
}
|
|
28105
|
+
return new Promise((resolve4, reject) => {
|
|
28106
|
+
const timeout = setTimeout(reject, timeoutMs);
|
|
28107
|
+
logStream.end(() => {
|
|
28108
|
+
clearTimeout(timeout);
|
|
28109
|
+
resolve4();
|
|
28110
|
+
});
|
|
28111
|
+
});
|
|
28112
|
+
}
|
|
28113
|
+
function write(message, args2, body) {
|
|
28114
|
+
if (logStream) {
|
|
28115
|
+
logStream.write(`${(/* @__PURE__ */ new Date()).toISOString()} ${message}${formatArgs(args2)}
|
|
28116
|
+
`);
|
|
28117
|
+
if (body) {
|
|
28118
|
+
logStream.write(`${body}
|
|
28119
|
+
`);
|
|
28089
28120
|
}
|
|
28090
28121
|
} else {
|
|
28091
|
-
console.error(
|
|
28122
|
+
console.error(message, ...args2);
|
|
28123
|
+
if (body) {
|
|
28124
|
+
console.error(body);
|
|
28125
|
+
}
|
|
28092
28126
|
}
|
|
28093
28127
|
}
|
|
28128
|
+
function log(message, ...args2) {
|
|
28129
|
+
write(`[firefox-devtools-mcp] ${message}`, args2);
|
|
28130
|
+
}
|
|
28094
28131
|
function logDebug(message, ...args2) {
|
|
28095
28132
|
if (process.env.DEBUG === "*" || process.env.DEBUG?.includes("firefox-devtools")) {
|
|
28096
|
-
|
|
28133
|
+
write(`[firefox-devtools-mcp] DEBUG: ${message}`, args2);
|
|
28134
|
+
}
|
|
28135
|
+
}
|
|
28136
|
+
function logError(message, error2) {
|
|
28137
|
+
if (error2 instanceof Error) {
|
|
28138
|
+
write(`[firefox-devtools-mcp] ERROR: ${message}`, [error2.message], error2.stack);
|
|
28139
|
+
} else {
|
|
28140
|
+
write(`[firefox-devtools-mcp] ERROR: ${message}`, [error2]);
|
|
28097
28141
|
}
|
|
28098
28142
|
}
|
|
28143
|
+
function setupLogFile(filePath) {
|
|
28144
|
+
logStream = fs.createWriteStream(filePath, { flags: "a" });
|
|
28145
|
+
logStream.on("error", (error2) => {
|
|
28146
|
+
console.error(`[firefox-devtools-mcp] Error writing to log file: ${error2.message}`);
|
|
28147
|
+
logStream = null;
|
|
28148
|
+
});
|
|
28149
|
+
}
|
|
28150
|
+
var logStream;
|
|
28099
28151
|
var init_logger = __esm({
|
|
28100
28152
|
"src/utils/logger.ts"() {
|
|
28101
28153
|
"use strict";
|
|
28154
|
+
logStream = null;
|
|
28102
28155
|
}
|
|
28103
28156
|
});
|
|
28104
28157
|
|
|
@@ -28210,11 +28263,12 @@ var init_core3 = __esm({
|
|
|
28210
28263
|
constructor(options) {
|
|
28211
28264
|
this.options = options;
|
|
28212
28265
|
}
|
|
28213
|
-
driver = null;
|
|
28214
28266
|
currentContextId = null;
|
|
28215
|
-
|
|
28216
|
-
|
|
28267
|
+
driver = null;
|
|
28268
|
+
firefoxVersion = null;
|
|
28217
28269
|
logFileFd;
|
|
28270
|
+
logFilePath;
|
|
28271
|
+
originalEnv = {};
|
|
28218
28272
|
profileWarning = null;
|
|
28219
28273
|
/**
|
|
28220
28274
|
* Launch Firefox (or connect to an existing instance) and establish BiDi connection
|
|
@@ -28306,6 +28360,9 @@ var init_core3 = __esm({
|
|
|
28306
28360
|
for (const [name, value] of Object.entries(this.options.prefs)) {
|
|
28307
28361
|
firefoxOptions.setPreference(name, value);
|
|
28308
28362
|
}
|
|
28363
|
+
if (this.options.prefs["remote.prefs.recommended"] === false && !("app.update.disabledForTesting" in this.options.prefs)) {
|
|
28364
|
+
firefoxOptions.setPreference("app.update.disabledForTesting", true);
|
|
28365
|
+
}
|
|
28309
28366
|
}
|
|
28310
28367
|
let serviceBuilder;
|
|
28311
28368
|
if (process.platform === "win32") {
|
|
@@ -28320,11 +28377,18 @@ var init_core3 = __esm({
|
|
|
28320
28377
|
serviceBuilder.setStdio(["ignore", this.logFileFd, this.logFileFd]);
|
|
28321
28378
|
log(`Capturing Firefox output to: ${this.logFilePath}`);
|
|
28322
28379
|
}
|
|
28380
|
+
const remoteLogLevel = this.options.prefs?.["remote.log.level"];
|
|
28381
|
+
if (remoteLogLevel && typeof remoteLogLevel === "string") {
|
|
28382
|
+
serviceBuilder.addArguments("--log", remoteLogLevel.toLowerCase());
|
|
28383
|
+
}
|
|
28323
28384
|
this.driver = await new Builder().forBrowser(Browser.FIREFOX).setFirefoxOptions(firefoxOptions).setFirefoxService(serviceBuilder).build();
|
|
28324
28385
|
}
|
|
28325
28386
|
log(
|
|
28326
28387
|
this.options.connectExisting ? "Connected to existing Firefox" : "Firefox launched with BiDi"
|
|
28327
28388
|
);
|
|
28389
|
+
const driverCapabilities = await this.driver.getCapabilities();
|
|
28390
|
+
this.firefoxVersion = driverCapabilities.get("browserVersion") ?? null;
|
|
28391
|
+
logDebug(`Browser version: ${this.firefoxVersion}`);
|
|
28328
28392
|
this.currentContextId = await this.driver.getWindowHandle();
|
|
28329
28393
|
logDebug(`Browsing context ID: ${this.currentContextId}`);
|
|
28330
28394
|
if (this.options.startUrl && !this.options.connectExisting) {
|
|
@@ -28358,24 +28422,6 @@ var init_core3 = __esm({
|
|
|
28358
28422
|
return false;
|
|
28359
28423
|
}
|
|
28360
28424
|
}
|
|
28361
|
-
/**
|
|
28362
|
-
* Reset driver state (used when Firefox is detected as closed)
|
|
28363
|
-
*/
|
|
28364
|
-
reset() {
|
|
28365
|
-
if (this.driver) {
|
|
28366
|
-
const d = this.driver;
|
|
28367
|
-
if (d._bidiConnection) {
|
|
28368
|
-
d._bidiConnection.close();
|
|
28369
|
-
d._bidiConnection = void 0;
|
|
28370
|
-
}
|
|
28371
|
-
if ("quit" in this.driver) {
|
|
28372
|
-
void this.driver.quit();
|
|
28373
|
-
}
|
|
28374
|
-
}
|
|
28375
|
-
this.driver = null;
|
|
28376
|
-
this.currentContextId = null;
|
|
28377
|
-
logDebug("Driver state reset");
|
|
28378
|
-
}
|
|
28379
28425
|
/**
|
|
28380
28426
|
* Get current browsing context ID
|
|
28381
28427
|
*/
|
|
@@ -28388,6 +28434,12 @@ var init_core3 = __esm({
|
|
|
28388
28434
|
setCurrentContextId(contextId) {
|
|
28389
28435
|
this.currentContextId = contextId;
|
|
28390
28436
|
}
|
|
28437
|
+
/**
|
|
28438
|
+
* Get the current firefox version, as a string (eg "153.0a1")
|
|
28439
|
+
*/
|
|
28440
|
+
getFirefoxVersion() {
|
|
28441
|
+
return this.firefoxVersion;
|
|
28442
|
+
}
|
|
28391
28443
|
/**
|
|
28392
28444
|
* Get log file path
|
|
28393
28445
|
*/
|
|
@@ -28473,20 +28525,47 @@ var init_core3 = __esm({
|
|
|
28473
28525
|
}
|
|
28474
28526
|
/**
|
|
28475
28527
|
* Close driver and cleanup.
|
|
28476
|
-
*
|
|
28477
|
-
*
|
|
28528
|
+
* - Tries graceful quit() with a timeout; on timeout, force-kills via onQuit_().
|
|
28529
|
+
* - Restores env vars, closes log fd, clears all state.
|
|
28530
|
+
* - Never throws — callers can rely on cleanup completing.
|
|
28478
28531
|
*/
|
|
28479
28532
|
async close() {
|
|
28480
|
-
if (this.driver) {
|
|
28481
|
-
|
|
28482
|
-
|
|
28483
|
-
|
|
28484
|
-
|
|
28533
|
+
if (!this.driver) {
|
|
28534
|
+
return;
|
|
28535
|
+
}
|
|
28536
|
+
const webdriver = this.driver;
|
|
28537
|
+
const webdriverQuitTimeout = 5e3;
|
|
28538
|
+
this.driver = null;
|
|
28539
|
+
this.currentContextId = null;
|
|
28540
|
+
this.logFilePath = void 0;
|
|
28541
|
+
this.profileWarning = null;
|
|
28542
|
+
if (webdriver._bidiConnection) {
|
|
28543
|
+
try {
|
|
28544
|
+
webdriver._bidiConnection.close();
|
|
28545
|
+
} catch {
|
|
28546
|
+
} finally {
|
|
28547
|
+
webdriver._bidiConnection = void 0;
|
|
28485
28548
|
}
|
|
28486
|
-
|
|
28487
|
-
|
|
28549
|
+
}
|
|
28550
|
+
if ("quit" in webdriver) {
|
|
28551
|
+
let timer;
|
|
28552
|
+
try {
|
|
28553
|
+
await Promise.race([
|
|
28554
|
+
webdriver.quit(),
|
|
28555
|
+
new Promise((_, reject) => {
|
|
28556
|
+
timer = setTimeout(() => reject(new Error("close timeout")), webdriverQuitTimeout);
|
|
28557
|
+
})
|
|
28558
|
+
]);
|
|
28559
|
+
} catch {
|
|
28560
|
+
const webdriverHasOnQuit = typeof webdriver.onQuit_ === "function";
|
|
28561
|
+
logDebug("WebDriver.quit() timed out or failed - force killing geckodriver");
|
|
28562
|
+
if (webdriverHasOnQuit) {
|
|
28563
|
+
void webdriver.onQuit_().catch(() => {
|
|
28564
|
+
});
|
|
28565
|
+
}
|
|
28566
|
+
} finally {
|
|
28567
|
+
clearTimeout(timer);
|
|
28488
28568
|
}
|
|
28489
|
-
this.driver = null;
|
|
28490
28569
|
}
|
|
28491
28570
|
if (this.logFileFd !== void 0) {
|
|
28492
28571
|
try {
|
|
@@ -28876,12 +28955,135 @@ var init_network = __esm({
|
|
|
28876
28955
|
}
|
|
28877
28956
|
});
|
|
28878
28957
|
|
|
28958
|
+
// src/firefox/events/debugging.ts
|
|
28959
|
+
var MAX_LOGPOINT_RESULTS, DebuggingEvents;
|
|
28960
|
+
var init_debugging = __esm({
|
|
28961
|
+
"src/firefox/events/debugging.ts"() {
|
|
28962
|
+
"use strict";
|
|
28963
|
+
init_logger();
|
|
28964
|
+
MAX_LOGPOINT_RESULTS = 100;
|
|
28965
|
+
DebuggingEvents = class {
|
|
28966
|
+
constructor(driver, sendBiDiCommand) {
|
|
28967
|
+
this.driver = driver;
|
|
28968
|
+
this.sendBiDiCommand = sendBiDiCommand;
|
|
28969
|
+
}
|
|
28970
|
+
logpoints = /* @__PURE__ */ new Map();
|
|
28971
|
+
subscribed = false;
|
|
28972
|
+
/**
|
|
28973
|
+
* Subscribe to moz:debugging events
|
|
28974
|
+
*/
|
|
28975
|
+
async subscribe(contextId) {
|
|
28976
|
+
if (this.subscribed) {
|
|
28977
|
+
return;
|
|
28978
|
+
}
|
|
28979
|
+
const bidi = await this.driver.getBidi();
|
|
28980
|
+
try {
|
|
28981
|
+
await bidi.subscribe("moz:debugging.paused", contextId ? [contextId] : void 0);
|
|
28982
|
+
await bidi.subscribe("moz:debugging.resumed", contextId ? [contextId] : void 0);
|
|
28983
|
+
} catch {
|
|
28984
|
+
logDebug(
|
|
28985
|
+
"Debugging events subscription skipped (may not be available in this Firefox version)"
|
|
28986
|
+
);
|
|
28987
|
+
}
|
|
28988
|
+
const ws = bidi.socket;
|
|
28989
|
+
ws.on("message", (data) => {
|
|
28990
|
+
try {
|
|
28991
|
+
const payload = JSON.parse(data.toString());
|
|
28992
|
+
if (payload?.method === "moz:debugging.paused") {
|
|
28993
|
+
const { context, url: url2, line, column } = payload.params;
|
|
28994
|
+
const logpointId = this.findLogpointByLocation(url2, line);
|
|
28995
|
+
if (logpointId) {
|
|
28996
|
+
void this.handleLogpointPause(context, logpointId);
|
|
28997
|
+
return;
|
|
28998
|
+
}
|
|
28999
|
+
logDebug(`moz:Debugging paused in context: ${context} at ${url2}:${line}:${column}`);
|
|
29000
|
+
}
|
|
29001
|
+
if (payload?.method === "moz:debugging.resumed") {
|
|
29002
|
+
logDebug(`moz:Debugging resumed in context: ${payload.params.context}`);
|
|
29003
|
+
}
|
|
29004
|
+
} catch {
|
|
29005
|
+
}
|
|
29006
|
+
});
|
|
29007
|
+
this.subscribed = true;
|
|
29008
|
+
logDebug("moz:debugging listener active");
|
|
29009
|
+
}
|
|
29010
|
+
addLogpoint(logpointId, url2, line, expression) {
|
|
29011
|
+
this.logpoints.set(logpointId, {
|
|
29012
|
+
location: { url: url2, line },
|
|
29013
|
+
expression,
|
|
29014
|
+
results: [],
|
|
29015
|
+
capped: false
|
|
29016
|
+
});
|
|
29017
|
+
}
|
|
29018
|
+
removeLogpoint(logpointId) {
|
|
29019
|
+
this.logpoints.delete(logpointId);
|
|
29020
|
+
}
|
|
29021
|
+
getLogpointResults(logpointId) {
|
|
29022
|
+
return this.logpoints.get(logpointId)?.results ?? null;
|
|
29023
|
+
}
|
|
29024
|
+
findLogpointByLocation(url2, line) {
|
|
29025
|
+
for (const [logpointId, entry] of this.logpoints) {
|
|
29026
|
+
if (entry.location.url === url2 && entry.location.line === line) {
|
|
29027
|
+
return logpointId;
|
|
29028
|
+
}
|
|
29029
|
+
}
|
|
29030
|
+
return null;
|
|
29031
|
+
}
|
|
29032
|
+
async handleLogpointPause(contextId, logpointId) {
|
|
29033
|
+
const entry = this.logpoints.get(logpointId);
|
|
29034
|
+
if (!entry) {
|
|
29035
|
+
return;
|
|
29036
|
+
}
|
|
29037
|
+
logDebug(`Logpoint hit: ${logpointId} in context ${contextId}`);
|
|
29038
|
+
try {
|
|
29039
|
+
const result = await this.sendBiDiCommand("script.evaluate", {
|
|
29040
|
+
expression: entry.expression,
|
|
29041
|
+
target: { context: contextId },
|
|
29042
|
+
awaitPromise: false
|
|
29043
|
+
});
|
|
29044
|
+
const evalResult = result;
|
|
29045
|
+
if (evalResult.type === "exception") {
|
|
29046
|
+
entry.results.push({
|
|
29047
|
+
value: null,
|
|
29048
|
+
error: evalResult.exceptionDetails?.text ?? "Unknown error",
|
|
29049
|
+
timestamp: Date.now()
|
|
29050
|
+
});
|
|
29051
|
+
} else {
|
|
29052
|
+
entry.results.push({
|
|
29053
|
+
value: evalResult.result,
|
|
29054
|
+
timestamp: Date.now()
|
|
29055
|
+
});
|
|
29056
|
+
}
|
|
29057
|
+
} catch (error2) {
|
|
29058
|
+
entry.results.push({
|
|
29059
|
+
value: null,
|
|
29060
|
+
error: String(error2),
|
|
29061
|
+
timestamp: Date.now()
|
|
29062
|
+
});
|
|
29063
|
+
} finally {
|
|
29064
|
+
if (entry.results.length > MAX_LOGPOINT_RESULTS) {
|
|
29065
|
+
entry.results.splice(0, entry.results.length - MAX_LOGPOINT_RESULTS);
|
|
29066
|
+
if (!entry.capped) {
|
|
29067
|
+
entry.capped = true;
|
|
29068
|
+
logDebug(`Logpoint ${logpointId}: result buffer capped at ${MAX_LOGPOINT_RESULTS}`);
|
|
29069
|
+
}
|
|
29070
|
+
}
|
|
29071
|
+
await this.sendBiDiCommand("moz:debugging.resume", { context: contextId }).catch((err) => {
|
|
29072
|
+
logDebug(`Failed to resume after logpoint: ${String(err)}`);
|
|
29073
|
+
});
|
|
29074
|
+
}
|
|
29075
|
+
}
|
|
29076
|
+
};
|
|
29077
|
+
}
|
|
29078
|
+
});
|
|
29079
|
+
|
|
28879
29080
|
// src/firefox/events/index.ts
|
|
28880
29081
|
var init_events = __esm({
|
|
28881
29082
|
"src/firefox/events/index.ts"() {
|
|
28882
29083
|
"use strict";
|
|
28883
29084
|
init_console();
|
|
28884
29085
|
init_network();
|
|
29086
|
+
init_debugging();
|
|
28885
29087
|
}
|
|
28886
29088
|
});
|
|
28887
29089
|
|
|
@@ -29793,6 +29995,7 @@ var init_firefox = __esm({
|
|
|
29793
29995
|
core;
|
|
29794
29996
|
consoleEvents = null;
|
|
29795
29997
|
networkEvents = null;
|
|
29998
|
+
debuggingEvents = null;
|
|
29796
29999
|
dom = null;
|
|
29797
30000
|
pages = null;
|
|
29798
30001
|
snapshot = null;
|
|
@@ -29821,6 +30024,10 @@ var init_firefox = __esm({
|
|
|
29821
30024
|
onNavigate,
|
|
29822
30025
|
autoClearOnNavigate: false
|
|
29823
30026
|
});
|
|
30027
|
+
this.debuggingEvents = new DebuggingEvents(
|
|
30028
|
+
driver,
|
|
30029
|
+
(method, params) => this.core.sendBiDiCommand(method, params)
|
|
30030
|
+
);
|
|
29824
30031
|
}
|
|
29825
30032
|
this.dom = new DomInteractions(
|
|
29826
30033
|
driver,
|
|
@@ -29848,6 +30055,14 @@ var init_firefox = __esm({
|
|
|
29848
30055
|
this.networkEvents = null;
|
|
29849
30056
|
}
|
|
29850
30057
|
}
|
|
30058
|
+
if (this.debuggingEvents) {
|
|
30059
|
+
try {
|
|
30060
|
+
await this.debuggingEvents.subscribe();
|
|
30061
|
+
} catch {
|
|
30062
|
+
logDebug("Debugging events unavailable (BiDi not supported by this Firefox session)");
|
|
30063
|
+
this.debuggingEvents = null;
|
|
30064
|
+
}
|
|
30065
|
+
}
|
|
29851
30066
|
}
|
|
29852
30067
|
// ============================================================================
|
|
29853
30068
|
// DOM / Evaluate
|
|
@@ -30141,6 +30356,48 @@ var init_firefox = __esm({
|
|
|
30141
30356
|
async isConnected() {
|
|
30142
30357
|
return await this.core.isConnected();
|
|
30143
30358
|
}
|
|
30359
|
+
/**
|
|
30360
|
+
* Get current browser version (eg "153.0a1").
|
|
30361
|
+
* @internal
|
|
30362
|
+
*/
|
|
30363
|
+
getFirefoxVersion() {
|
|
30364
|
+
return this.core.getFirefoxVersion();
|
|
30365
|
+
}
|
|
30366
|
+
/**
|
|
30367
|
+
* @internal
|
|
30368
|
+
*/
|
|
30369
|
+
async setLogpoint(url2, line, expression) {
|
|
30370
|
+
if (!this.debuggingEvents) {
|
|
30371
|
+
throw new Error("Debugging events not available");
|
|
30372
|
+
}
|
|
30373
|
+
const result = await this.core.sendBiDiCommand("moz:debugging.setBreakpoint", {
|
|
30374
|
+
location: { url: url2, line }
|
|
30375
|
+
});
|
|
30376
|
+
const logpointId = result.breakpoint;
|
|
30377
|
+
this.debuggingEvents.addLogpoint(logpointId, url2, line, expression);
|
|
30378
|
+
return logpointId;
|
|
30379
|
+
}
|
|
30380
|
+
/**
|
|
30381
|
+
* @internal
|
|
30382
|
+
*/
|
|
30383
|
+
async removeLogpoint(logpointId) {
|
|
30384
|
+
if (!this.debuggingEvents) {
|
|
30385
|
+
throw new Error("Debugging events not available");
|
|
30386
|
+
}
|
|
30387
|
+
await this.core.sendBiDiCommand("moz:debugging.removeBreakpoint", {
|
|
30388
|
+
breakpoint: logpointId
|
|
30389
|
+
});
|
|
30390
|
+
this.debuggingEvents.removeLogpoint(logpointId);
|
|
30391
|
+
}
|
|
30392
|
+
/**
|
|
30393
|
+
* @internal
|
|
30394
|
+
*/
|
|
30395
|
+
getLogpointResults(logpointId) {
|
|
30396
|
+
if (!this.debuggingEvents) {
|
|
30397
|
+
return null;
|
|
30398
|
+
}
|
|
30399
|
+
return this.debuggingEvents.getLogpointResults(logpointId);
|
|
30400
|
+
}
|
|
30144
30401
|
/**
|
|
30145
30402
|
* Get log file path (if logging is enabled)
|
|
30146
30403
|
*/
|
|
@@ -30160,23 +30417,22 @@ var init_firefox = __esm({
|
|
|
30160
30417
|
getOptions() {
|
|
30161
30418
|
return this.core.getOptions();
|
|
30162
30419
|
}
|
|
30163
|
-
|
|
30164
|
-
|
|
30165
|
-
|
|
30166
|
-
|
|
30167
|
-
|
|
30420
|
+
// ============================================================================
|
|
30421
|
+
// Cleanup
|
|
30422
|
+
// ============================================================================
|
|
30423
|
+
async close() {
|
|
30424
|
+
try {
|
|
30425
|
+
await this.core.close();
|
|
30426
|
+
} catch (error2) {
|
|
30427
|
+
logDebug(`close() failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
30428
|
+
}
|
|
30168
30429
|
this.consoleEvents = null;
|
|
30169
30430
|
this.networkEvents = null;
|
|
30431
|
+
this.debuggingEvents = null;
|
|
30170
30432
|
this.dom = null;
|
|
30171
30433
|
this.pages = null;
|
|
30172
30434
|
this.snapshot = null;
|
|
30173
30435
|
}
|
|
30174
|
-
// ============================================================================
|
|
30175
|
-
// Cleanup
|
|
30176
|
-
// ============================================================================
|
|
30177
|
-
async close() {
|
|
30178
|
-
await this.core.close();
|
|
30179
|
-
}
|
|
30180
30436
|
};
|
|
30181
30437
|
}
|
|
30182
30438
|
});
|
|
@@ -30458,7 +30714,68 @@ var init_pages2 = __esm({
|
|
|
30458
30714
|
}
|
|
30459
30715
|
});
|
|
30460
30716
|
|
|
30461
|
-
// src/
|
|
30717
|
+
// src/utils/remote-value.ts
|
|
30718
|
+
function remoteValueToNative(rv) {
|
|
30719
|
+
if (!rv || typeof rv !== "object") {
|
|
30720
|
+
return rv;
|
|
30721
|
+
}
|
|
30722
|
+
const { type, value } = rv;
|
|
30723
|
+
switch (type) {
|
|
30724
|
+
case "undefined":
|
|
30725
|
+
return void 0;
|
|
30726
|
+
case "null":
|
|
30727
|
+
return null;
|
|
30728
|
+
case "string":
|
|
30729
|
+
case "boolean":
|
|
30730
|
+
return value;
|
|
30731
|
+
case "number":
|
|
30732
|
+
if (value === "NaN") {
|
|
30733
|
+
return "NaN";
|
|
30734
|
+
}
|
|
30735
|
+
if (value === "Infinity") {
|
|
30736
|
+
return "Infinity";
|
|
30737
|
+
}
|
|
30738
|
+
if (value === "-Infinity") {
|
|
30739
|
+
return "-Infinity";
|
|
30740
|
+
}
|
|
30741
|
+
if (value === "-0") {
|
|
30742
|
+
return "-0";
|
|
30743
|
+
}
|
|
30744
|
+
return value;
|
|
30745
|
+
case "bigint":
|
|
30746
|
+
return `${value}n`;
|
|
30747
|
+
case "array":
|
|
30748
|
+
return value.map(remoteValueToNative);
|
|
30749
|
+
case "object":
|
|
30750
|
+
return Object.fromEntries(
|
|
30751
|
+
value.map(([k, v]) => [k, remoteValueToNative(v)])
|
|
30752
|
+
);
|
|
30753
|
+
case "map":
|
|
30754
|
+
return Object.fromEntries(
|
|
30755
|
+
value.map(([k, v]) => [
|
|
30756
|
+
typeof k === "object" ? JSON.stringify(remoteValueToNative(k)) : String(k),
|
|
30757
|
+
remoteValueToNative(v)
|
|
30758
|
+
])
|
|
30759
|
+
);
|
|
30760
|
+
case "set":
|
|
30761
|
+
return value.map(remoteValueToNative);
|
|
30762
|
+
case "regexp": {
|
|
30763
|
+
const { pattern, flags } = value;
|
|
30764
|
+
return `/${pattern}/${flags ?? ""}`;
|
|
30765
|
+
}
|
|
30766
|
+
case "date":
|
|
30767
|
+
return value;
|
|
30768
|
+
default:
|
|
30769
|
+
return `[${type}]`;
|
|
30770
|
+
}
|
|
30771
|
+
}
|
|
30772
|
+
var init_remote_value = __esm({
|
|
30773
|
+
"src/utils/remote-value.ts"() {
|
|
30774
|
+
"use strict";
|
|
30775
|
+
}
|
|
30776
|
+
});
|
|
30777
|
+
|
|
30778
|
+
// src/utils/js-validation.ts
|
|
30462
30779
|
function validateFunction(fnString) {
|
|
30463
30780
|
if (!fnString || typeof fnString !== "string") {
|
|
30464
30781
|
throw new Error("function parameter is required and must be a string");
|
|
@@ -30482,6 +30799,15 @@ Valid examples:
|
|
|
30482
30799
|
);
|
|
30483
30800
|
}
|
|
30484
30801
|
}
|
|
30802
|
+
var MAX_FUNCTION_SIZE;
|
|
30803
|
+
var init_js_validation = __esm({
|
|
30804
|
+
"src/utils/js-validation.ts"() {
|
|
30805
|
+
"use strict";
|
|
30806
|
+
MAX_FUNCTION_SIZE = 16 * 1024;
|
|
30807
|
+
}
|
|
30808
|
+
});
|
|
30809
|
+
|
|
30810
|
+
// src/tools/script.ts
|
|
30485
30811
|
async function handleEvaluateScript(args2) {
|
|
30486
30812
|
try {
|
|
30487
30813
|
const {
|
|
@@ -30492,17 +30818,13 @@ async function handleEvaluateScript(args2) {
|
|
|
30492
30818
|
validateFunction(fnString);
|
|
30493
30819
|
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
30494
30820
|
const firefox3 = await getFirefox2();
|
|
30495
|
-
const driver = firefox3.getDriver();
|
|
30496
|
-
if (!driver) {
|
|
30497
|
-
throw new Error("WebDriver not available");
|
|
30498
|
-
}
|
|
30499
30821
|
const scriptTimeout = timeout ?? DEFAULT_TIMEOUT;
|
|
30500
30822
|
const resolvedArgs = [];
|
|
30501
30823
|
if (fnArgs && fnArgs.length > 0) {
|
|
30502
30824
|
for (const arg of fnArgs) {
|
|
30503
30825
|
try {
|
|
30504
30826
|
const element = await firefox3.resolveUidToElement(arg.uid);
|
|
30505
|
-
resolvedArgs.push(element);
|
|
30827
|
+
resolvedArgs.push({ sharedId: await element.getId() });
|
|
30506
30828
|
} catch (error2) {
|
|
30507
30829
|
const errorMsg = error2.message;
|
|
30508
30830
|
if (errorMsg.includes("stale") || errorMsg.includes("Snapshot") || errorMsg.includes("UID")) {
|
|
@@ -30517,40 +30839,55 @@ Please call take_snapshot to get fresh UIDs and try again.`
|
|
|
30517
30839
|
}
|
|
30518
30840
|
}
|
|
30519
30841
|
}
|
|
30520
|
-
const
|
|
30521
|
-
|
|
30522
|
-
|
|
30523
|
-
|
|
30524
|
-
|
|
30525
|
-
|
|
30526
|
-
await
|
|
30527
|
-
|
|
30528
|
-
|
|
30529
|
-
|
|
30530
|
-
|
|
30531
|
-
output += "\n```";
|
|
30532
|
-
return successResponse(output);
|
|
30533
|
-
} catch (error2) {
|
|
30534
|
-
const errorMsg = error2.message;
|
|
30535
|
-
if (errorMsg.includes("timeout") || errorMsg.includes("Timeout")) {
|
|
30536
|
-
const timeoutValue = args2?.timeout ?? DEFAULT_TIMEOUT;
|
|
30842
|
+
const callFunctionPromise = firefox3.sendBiDiCommand("script.callFunction", {
|
|
30843
|
+
functionDeclaration: fnString,
|
|
30844
|
+
awaitPromise: true,
|
|
30845
|
+
arguments: resolvedArgs,
|
|
30846
|
+
target: { context: firefox3.getCurrentContextId() }
|
|
30847
|
+
});
|
|
30848
|
+
const result = await Promise.race([
|
|
30849
|
+
new Promise((r) => setTimeout(() => r(TIMEOUT), scriptTimeout)),
|
|
30850
|
+
callFunctionPromise
|
|
30851
|
+
]);
|
|
30852
|
+
if (result === TIMEOUT) {
|
|
30537
30853
|
return errorResponse(
|
|
30538
30854
|
new Error(
|
|
30539
|
-
`Script execution timed out (exceeded ${
|
|
30855
|
+
`Script execution timed out (exceeded ${scriptTimeout}ms).
|
|
30540
30856
|
|
|
30541
30857
|
The function may contain an infinite loop or be waiting for a slow operation.
|
|
30542
30858
|
Try simplifying the script or increasing the timeout parameter.`
|
|
30543
30859
|
)
|
|
30544
30860
|
);
|
|
30861
|
+
} else if (result.type === EvaluateResultType.Success) {
|
|
30862
|
+
let output = "Script ran on page and returned:\n";
|
|
30863
|
+
output += "```json\n";
|
|
30864
|
+
output += JSON.stringify(remoteValueToNative(result.result), null, 2);
|
|
30865
|
+
output += "\n```";
|
|
30866
|
+
return successResponse(output);
|
|
30867
|
+
} else if (result.type === EvaluateResultType.Exception) {
|
|
30868
|
+
const exceptionDetails = result.exceptionDetails;
|
|
30869
|
+
return errorResponse(
|
|
30870
|
+
new Error(
|
|
30871
|
+
`Script execution failed: ${exceptionDetails.text}
|
|
30872
|
+
|
|
30873
|
+
\`\`\`json
|
|
30874
|
+
` + JSON.stringify(remoteValueToNative(exceptionDetails.exception), null, 2) + "\n```"
|
|
30875
|
+
)
|
|
30876
|
+
);
|
|
30877
|
+
} else {
|
|
30878
|
+
return errorResponse(`Unexpected script.callFunction result type: ${result.type}`);
|
|
30545
30879
|
}
|
|
30880
|
+
} catch (error2) {
|
|
30546
30881
|
return errorResponse(error2);
|
|
30547
30882
|
}
|
|
30548
30883
|
}
|
|
30549
|
-
var evaluateScriptTool,
|
|
30884
|
+
var evaluateScriptTool, DEFAULT_TIMEOUT, TIMEOUT, EvaluateResultType;
|
|
30550
30885
|
var init_script = __esm({
|
|
30551
30886
|
"src/tools/script.ts"() {
|
|
30552
30887
|
"use strict";
|
|
30553
30888
|
init_response_helpers();
|
|
30889
|
+
init_remote_value();
|
|
30890
|
+
init_js_validation();
|
|
30554
30891
|
evaluateScriptTool = {
|
|
30555
30892
|
name: "evaluate_script",
|
|
30556
30893
|
description: "Execute JS function in page. Prefer UID tools for interactions.",
|
|
@@ -30583,8 +30920,12 @@ var init_script = __esm({
|
|
|
30583
30920
|
required: ["function"]
|
|
30584
30921
|
}
|
|
30585
30922
|
};
|
|
30586
|
-
MAX_FUNCTION_SIZE = 16 * 1024;
|
|
30587
30923
|
DEFAULT_TIMEOUT = 5e3;
|
|
30924
|
+
TIMEOUT = Symbol("Timeout");
|
|
30925
|
+
EvaluateResultType = {
|
|
30926
|
+
Exception: "exception",
|
|
30927
|
+
Success: "success"
|
|
30928
|
+
};
|
|
30588
30929
|
}
|
|
30589
30930
|
});
|
|
30590
30931
|
|
|
@@ -31797,10 +32138,12 @@ async function handleGetFirefoxInfo(_input) {
|
|
|
31797
32138
|
const firefox3 = await getFirefox();
|
|
31798
32139
|
const options = firefox3.getOptions();
|
|
31799
32140
|
const logFilePath = firefox3.getLogFilePath();
|
|
32141
|
+
const version3 = firefox3.getFirefoxVersion();
|
|
31800
32142
|
const info = [];
|
|
31801
32143
|
info.push("Firefox Instance Configuration");
|
|
31802
32144
|
info.push("");
|
|
31803
32145
|
info.push(`Binary: ${options.firefoxPath ?? "System Firefox (default)"}`);
|
|
32146
|
+
info.push(`Firefox version: ${version3 ?? "(unknown)"}`);
|
|
31804
32147
|
info.push(`Headless: ${options.headless ? "Yes" : "No"}`);
|
|
31805
32148
|
if (options.viewport) {
|
|
31806
32149
|
info.push(`Viewport: ${options.viewport.width}x${options.viewport.height}`);
|
|
@@ -31873,11 +32216,7 @@ async function handleRestartFirefox(input) {
|
|
|
31873
32216
|
prefs: mergedPrefs
|
|
31874
32217
|
};
|
|
31875
32218
|
setNextLaunchOptions(newOptions);
|
|
31876
|
-
|
|
31877
|
-
await currentFirefox.close();
|
|
31878
|
-
} catch {
|
|
31879
|
-
}
|
|
31880
|
-
resetFirefox();
|
|
32219
|
+
await resetFirefox();
|
|
31881
32220
|
const changes = [];
|
|
31882
32221
|
if (firefoxPath && firefoxPath !== currentOptions.firefoxPath) {
|
|
31883
32222
|
changes.push(`Binary: ${firefoxPath}`);
|
|
@@ -31908,7 +32247,7 @@ ${changes.join("\n")}`
|
|
|
31908
32247
|
);
|
|
31909
32248
|
} else {
|
|
31910
32249
|
if (currentFirefox) {
|
|
31911
|
-
resetFirefox();
|
|
32250
|
+
await resetFirefox();
|
|
31912
32251
|
}
|
|
31913
32252
|
const resolvedFirefoxPath = firefoxPath ?? args.firefoxPath ?? void 0;
|
|
31914
32253
|
if (!resolvedFirefoxPath) {
|
|
@@ -32030,10 +32369,6 @@ var init_firefox_management = __esm({
|
|
|
32030
32369
|
});
|
|
32031
32370
|
|
|
32032
32371
|
// src/tools/privileged-context.ts
|
|
32033
|
-
function isLikelyStatement(input) {
|
|
32034
|
-
const trimmed = input.trim();
|
|
32035
|
-
return /^(const|let|var)\s/.test(trimmed);
|
|
32036
|
-
}
|
|
32037
32372
|
function formatContextList(contexts) {
|
|
32038
32373
|
if (contexts.length === 0) {
|
|
32039
32374
|
return "No privileged contexts found";
|
|
@@ -32096,41 +32431,46 @@ async function handleSelectPrivilegedContext(args2) {
|
|
|
32096
32431
|
}
|
|
32097
32432
|
async function handleEvaluatePrivilegedScript(args2) {
|
|
32098
32433
|
try {
|
|
32099
|
-
const {
|
|
32100
|
-
|
|
32101
|
-
throw new Error("expression parameter is required and must be a string");
|
|
32102
|
-
}
|
|
32103
|
-
if (isLikelyStatement(expression)) {
|
|
32104
|
-
return errorResponse(
|
|
32105
|
-
new Error(
|
|
32106
|
-
`Cannot evaluate statement: "${expression.substring(0, 50)}${expression.length > 50 ? "..." : ""}". This tool expects an expression, not a statement (const/let/var declarations are statements). To use statements, wrap them in an IIFE: (function() { const x = 1; return x; })()`
|
|
32107
|
-
)
|
|
32108
|
-
);
|
|
32109
|
-
}
|
|
32434
|
+
const { function: fnString } = args2;
|
|
32435
|
+
validateFunction(fnString);
|
|
32110
32436
|
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
32111
32437
|
const firefox3 = await getFirefox2();
|
|
32112
|
-
const
|
|
32113
|
-
|
|
32114
|
-
|
|
32115
|
-
|
|
32116
|
-
|
|
32117
|
-
|
|
32118
|
-
|
|
32438
|
+
const result = await firefox3.sendBiDiCommand("script.callFunction", {
|
|
32439
|
+
functionDeclaration: fnString,
|
|
32440
|
+
awaitPromise: true,
|
|
32441
|
+
arguments: [],
|
|
32442
|
+
target: { context: firefox3.getCurrentContextId() }
|
|
32443
|
+
});
|
|
32444
|
+
if (result.type === EvaluateResultType2.Success) {
|
|
32445
|
+
let output = "Script ran in chrome context and returned:\n";
|
|
32446
|
+
output += "```json\n";
|
|
32447
|
+
output += JSON.stringify(remoteValueToNative(result.result), null, 2);
|
|
32448
|
+
output += "\n```";
|
|
32449
|
+
return successResponse(output);
|
|
32450
|
+
} else if (result.type === EvaluateResultType2.Exception) {
|
|
32451
|
+
const exceptionDetails = result.exceptionDetails;
|
|
32119
32452
|
return errorResponse(
|
|
32120
32453
|
new Error(
|
|
32121
|
-
`Script execution failed: ${
|
|
32454
|
+
`Script execution failed: ${exceptionDetails.text}
|
|
32455
|
+
|
|
32456
|
+
\`\`\`json
|
|
32457
|
+
` + JSON.stringify(remoteValueToNative(exceptionDetails.exception), null, 2) + "\n```"
|
|
32122
32458
|
)
|
|
32123
32459
|
);
|
|
32460
|
+
} else {
|
|
32461
|
+
return errorResponse(`Unexpected script.callFunction result type: ${result.type}`);
|
|
32124
32462
|
}
|
|
32125
32463
|
} catch (error2) {
|
|
32126
32464
|
return errorResponse(error2);
|
|
32127
32465
|
}
|
|
32128
32466
|
}
|
|
32129
|
-
var listPrivilegedContextsTool, selectPrivilegedContextTool, evaluatePrivilegedScriptTool;
|
|
32467
|
+
var listPrivilegedContextsTool, selectPrivilegedContextTool, evaluatePrivilegedScriptTool, EvaluateResultType2;
|
|
32130
32468
|
var init_privileged_context = __esm({
|
|
32131
32469
|
"src/tools/privileged-context.ts"() {
|
|
32132
32470
|
"use strict";
|
|
32133
32471
|
init_response_helpers();
|
|
32472
|
+
init_js_validation();
|
|
32473
|
+
init_remote_value();
|
|
32134
32474
|
listPrivilegedContextsTool = {
|
|
32135
32475
|
name: "list_privileged_contexts",
|
|
32136
32476
|
description: "List privileged (privileged) browsing contexts. Requires MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1 env var. Use restart_firefox with env parameter to enable.",
|
|
@@ -32155,18 +32495,22 @@ var init_privileged_context = __esm({
|
|
|
32155
32495
|
};
|
|
32156
32496
|
evaluatePrivilegedScriptTool = {
|
|
32157
32497
|
name: "evaluate_privileged_script",
|
|
32158
|
-
description: "
|
|
32498
|
+
description: "Execute JS function in the current privileged context. Requires MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1 env var. Use select_privileged_context first to target a chrome context.",
|
|
32159
32499
|
inputSchema: {
|
|
32160
32500
|
type: "object",
|
|
32161
32501
|
properties: {
|
|
32162
|
-
|
|
32502
|
+
function: {
|
|
32163
32503
|
type: "string",
|
|
32164
|
-
description:
|
|
32504
|
+
description: 'JS function string, e.g. () => Services.prefs.getBoolPref("foo")'
|
|
32165
32505
|
}
|
|
32166
32506
|
},
|
|
32167
|
-
required: ["
|
|
32507
|
+
required: ["function"]
|
|
32168
32508
|
}
|
|
32169
32509
|
};
|
|
32510
|
+
EvaluateResultType2 = {
|
|
32511
|
+
Exception: "exception",
|
|
32512
|
+
Success: "success"
|
|
32513
|
+
};
|
|
32170
32514
|
}
|
|
32171
32515
|
});
|
|
32172
32516
|
|
|
@@ -32641,6 +32985,354 @@ var init_webextension = __esm({
|
|
|
32641
32985
|
}
|
|
32642
32986
|
});
|
|
32643
32987
|
|
|
32988
|
+
// src/utils/version.ts
|
|
32989
|
+
function getMajorVersion(version3) {
|
|
32990
|
+
const [major2, _rhs] = version3.split(".");
|
|
32991
|
+
if (!major2) {
|
|
32992
|
+
throw new Error(`Unable to parse Firefox version ${version3}`);
|
|
32993
|
+
}
|
|
32994
|
+
return Number.parseInt(major2, 10);
|
|
32995
|
+
}
|
|
32996
|
+
function compareVersions(versionA, versionB) {
|
|
32997
|
+
const majorA = getMajorVersion(versionA);
|
|
32998
|
+
const majorB = getMajorVersion(versionB);
|
|
32999
|
+
if (majorA < majorB) {
|
|
33000
|
+
return -1;
|
|
33001
|
+
}
|
|
33002
|
+
if (majorA > majorB) {
|
|
33003
|
+
return 1;
|
|
33004
|
+
}
|
|
33005
|
+
return 0;
|
|
33006
|
+
}
|
|
33007
|
+
var init_version = __esm({
|
|
33008
|
+
"src/utils/version.ts"() {
|
|
33009
|
+
"use strict";
|
|
33010
|
+
}
|
|
33011
|
+
});
|
|
33012
|
+
|
|
33013
|
+
// src/tools/debugging.ts
|
|
33014
|
+
function requireDebuggingSupport(firefox3) {
|
|
33015
|
+
const version3 = firefox3.getFirefoxVersion();
|
|
33016
|
+
if (version3 !== null && compareVersions(version3, MIN_VERSION) < 0) {
|
|
33017
|
+
throw new Error(
|
|
33018
|
+
`moz:debugging requires Firefox ${MIN_VERSION}+, current version is ${version3}`
|
|
33019
|
+
);
|
|
33020
|
+
}
|
|
33021
|
+
}
|
|
33022
|
+
function requireContext(contextId) {
|
|
33023
|
+
if (!contextId) {
|
|
33024
|
+
throw new Error("No active browsing context");
|
|
33025
|
+
}
|
|
33026
|
+
return contextId;
|
|
33027
|
+
}
|
|
33028
|
+
async function handleEnableDebugger(_args) {
|
|
33029
|
+
try {
|
|
33030
|
+
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
33031
|
+
const firefox3 = await getFirefox2();
|
|
33032
|
+
requireDebuggingSupport(firefox3);
|
|
33033
|
+
await firefox3.sendBiDiCommand("moz:debugging.setDebuggerEnabled", { enabled: true });
|
|
33034
|
+
return successResponse("Debugger enabled");
|
|
33035
|
+
} catch (error2) {
|
|
33036
|
+
return errorResponse(error2);
|
|
33037
|
+
}
|
|
33038
|
+
}
|
|
33039
|
+
async function handleListScripts(_args) {
|
|
33040
|
+
try {
|
|
33041
|
+
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
33042
|
+
const firefox3 = await getFirefox2();
|
|
33043
|
+
requireDebuggingSupport(firefox3);
|
|
33044
|
+
const contextId = requireContext(firefox3.getCurrentContextId());
|
|
33045
|
+
const result = await firefox3.sendBiDiCommand("moz:debugging.listScripts", {
|
|
33046
|
+
context: contextId
|
|
33047
|
+
});
|
|
33048
|
+
const scripts = result.scripts;
|
|
33049
|
+
if (scripts.length === 0) {
|
|
33050
|
+
return successResponse("No scripts found");
|
|
33051
|
+
}
|
|
33052
|
+
return successResponse(scripts.join("\n"));
|
|
33053
|
+
} catch (error2) {
|
|
33054
|
+
return errorResponse(error2);
|
|
33055
|
+
}
|
|
33056
|
+
}
|
|
33057
|
+
async function handleGetScriptSource(args2) {
|
|
33058
|
+
try {
|
|
33059
|
+
const { scriptUrl } = args2;
|
|
33060
|
+
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
33061
|
+
const firefox3 = await getFirefox2();
|
|
33062
|
+
requireDebuggingSupport(firefox3);
|
|
33063
|
+
const contextId = requireContext(firefox3.getCurrentContextId());
|
|
33064
|
+
const result = await firefox3.sendBiDiCommand("moz:debugging.getScriptSource", {
|
|
33065
|
+
context: contextId,
|
|
33066
|
+
scriptUrl
|
|
33067
|
+
});
|
|
33068
|
+
return successResponse(result.source);
|
|
33069
|
+
} catch (error2) {
|
|
33070
|
+
return errorResponse(error2);
|
|
33071
|
+
}
|
|
33072
|
+
}
|
|
33073
|
+
async function handleSetLogpoint(args2) {
|
|
33074
|
+
try {
|
|
33075
|
+
const { url: url2, line, expression } = args2;
|
|
33076
|
+
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
33077
|
+
const firefox3 = await getFirefox2();
|
|
33078
|
+
requireDebuggingSupport(firefox3);
|
|
33079
|
+
const logpointId = await firefox3.setLogpoint(url2, line, expression);
|
|
33080
|
+
return successResponse(`Logpoint set (id: ${logpointId})`);
|
|
33081
|
+
} catch (error2) {
|
|
33082
|
+
return errorResponse(error2);
|
|
33083
|
+
}
|
|
33084
|
+
}
|
|
33085
|
+
async function handleRemoveLogpoint(args2) {
|
|
33086
|
+
try {
|
|
33087
|
+
const { logpoint } = args2;
|
|
33088
|
+
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
33089
|
+
const firefox3 = await getFirefox2();
|
|
33090
|
+
requireDebuggingSupport(firefox3);
|
|
33091
|
+
await firefox3.removeLogpoint(logpoint);
|
|
33092
|
+
return successResponse("Logpoint removed");
|
|
33093
|
+
} catch (error2) {
|
|
33094
|
+
return errorResponse(error2);
|
|
33095
|
+
}
|
|
33096
|
+
}
|
|
33097
|
+
async function handleGetLogpointResults(args2) {
|
|
33098
|
+
try {
|
|
33099
|
+
const { logpoint } = args2;
|
|
33100
|
+
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
33101
|
+
const firefox3 = await getFirefox2();
|
|
33102
|
+
requireDebuggingSupport(firefox3);
|
|
33103
|
+
const results = firefox3.getLogpointResults(logpoint);
|
|
33104
|
+
if (results === null) {
|
|
33105
|
+
return errorResponse(new Error(`Logpoint ${logpoint} not found`));
|
|
33106
|
+
}
|
|
33107
|
+
if (results.length === 0) {
|
|
33108
|
+
return successResponse("No results collected yet");
|
|
33109
|
+
}
|
|
33110
|
+
const lines = results.map((r, i) => {
|
|
33111
|
+
if (r.error) {
|
|
33112
|
+
return `[${i + 1}] Error: ${r.error}`;
|
|
33113
|
+
}
|
|
33114
|
+
return `[${i + 1}] ${JSON.stringify(remoteValueToNative(r.value))}`;
|
|
33115
|
+
});
|
|
33116
|
+
return successResponse(lines.join("\n"));
|
|
33117
|
+
} catch (error2) {
|
|
33118
|
+
return errorResponse(error2);
|
|
33119
|
+
}
|
|
33120
|
+
}
|
|
33121
|
+
var MIN_VERSION, enableDebuggerTool, listScriptsTool, getScriptSourceTool, setLogpointTool, removeLogpointTool, getLogpointResultsTool;
|
|
33122
|
+
var init_debugging2 = __esm({
|
|
33123
|
+
"src/tools/debugging.ts"() {
|
|
33124
|
+
"use strict";
|
|
33125
|
+
init_response_helpers();
|
|
33126
|
+
init_version();
|
|
33127
|
+
init_remote_value();
|
|
33128
|
+
MIN_VERSION = "153";
|
|
33129
|
+
enableDebuggerTool = {
|
|
33130
|
+
name: "enable_debugger",
|
|
33131
|
+
description: "Enable the JS debugger for the current page. Required before set_logpoint works. Requires Firefox 153+.",
|
|
33132
|
+
inputSchema: { type: "object", properties: {} }
|
|
33133
|
+
};
|
|
33134
|
+
listScriptsTool = {
|
|
33135
|
+
name: "list_scripts",
|
|
33136
|
+
description: "List all JavaScript files currently loaded in the page. Requires enable_debugger to have been called.",
|
|
33137
|
+
inputSchema: { type: "object", properties: {} }
|
|
33138
|
+
};
|
|
33139
|
+
getScriptSourceTool = {
|
|
33140
|
+
name: "get_script_source",
|
|
33141
|
+
description: "Get the source code of a JavaScript file loaded in the page. Requires enable_debugger to have been called.",
|
|
33142
|
+
inputSchema: {
|
|
33143
|
+
type: "object",
|
|
33144
|
+
properties: {
|
|
33145
|
+
scriptUrl: { type: "string", description: "URL of the script to retrieve." }
|
|
33146
|
+
},
|
|
33147
|
+
required: ["scriptUrl"]
|
|
33148
|
+
}
|
|
33149
|
+
};
|
|
33150
|
+
setLogpointTool = {
|
|
33151
|
+
name: "set_logpoint",
|
|
33152
|
+
description: "Set a logpoint at a specific location. When execution reaches that line, the expression is evaluated and the result is stored without pausing. Use get_logpoint_results to retrieve collected values. Requires enable_debugger to have been called.",
|
|
33153
|
+
inputSchema: {
|
|
33154
|
+
type: "object",
|
|
33155
|
+
properties: {
|
|
33156
|
+
url: { type: "string", description: "URL of the script." },
|
|
33157
|
+
line: { type: "number", description: "Line number (1-based)." },
|
|
33158
|
+
expression: {
|
|
33159
|
+
type: "string",
|
|
33160
|
+
description: "JavaScript expression to evaluate each time the logpoint is hit."
|
|
33161
|
+
}
|
|
33162
|
+
},
|
|
33163
|
+
required: ["url", "line", "expression"]
|
|
33164
|
+
}
|
|
33165
|
+
};
|
|
33166
|
+
removeLogpointTool = {
|
|
33167
|
+
name: "remove_logpoint",
|
|
33168
|
+
description: "Remove a previously set logpoint.",
|
|
33169
|
+
inputSchema: {
|
|
33170
|
+
type: "object",
|
|
33171
|
+
properties: {
|
|
33172
|
+
logpoint: { type: "string", description: "Logpoint id returned by set_logpoint." }
|
|
33173
|
+
},
|
|
33174
|
+
required: ["logpoint"]
|
|
33175
|
+
}
|
|
33176
|
+
};
|
|
33177
|
+
getLogpointResultsTool = {
|
|
33178
|
+
name: "get_logpoint_results",
|
|
33179
|
+
description: "Get the results collected by a logpoint since it was set.",
|
|
33180
|
+
inputSchema: {
|
|
33181
|
+
type: "object",
|
|
33182
|
+
properties: {
|
|
33183
|
+
logpoint: { type: "string", description: "Logpoint id returned by set_logpoint." }
|
|
33184
|
+
},
|
|
33185
|
+
required: ["logpoint"]
|
|
33186
|
+
}
|
|
33187
|
+
};
|
|
33188
|
+
}
|
|
33189
|
+
});
|
|
33190
|
+
|
|
33191
|
+
// src/tools/profiler.ts
|
|
33192
|
+
function checkProfilerSupported(firefox3) {
|
|
33193
|
+
const version3 = firefox3.getFirefoxVersion();
|
|
33194
|
+
if (version3 !== null && compareVersions(version3, MIN_FIREFOX_VERSION) < 0) {
|
|
33195
|
+
throw new Error(
|
|
33196
|
+
`moz:profiler requires Firefox ${MIN_FIREFOX_VERSION.split(".")[0]} or later (connected: ${version3})`
|
|
33197
|
+
);
|
|
33198
|
+
}
|
|
33199
|
+
}
|
|
33200
|
+
async function handleProfilerIsActive(_args) {
|
|
33201
|
+
try {
|
|
33202
|
+
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
33203
|
+
const firefox3 = await getFirefox2();
|
|
33204
|
+
checkProfilerSupported(firefox3);
|
|
33205
|
+
const result = await firefox3.sendBiDiCommand("moz:profiler.isActive", {});
|
|
33206
|
+
return successResponse(`Profiler is ${result.active ? "active" : "inactive"}`);
|
|
33207
|
+
} catch (error2) {
|
|
33208
|
+
return errorResponse(error2);
|
|
33209
|
+
}
|
|
33210
|
+
}
|
|
33211
|
+
async function handleProfilerStart(args2) {
|
|
33212
|
+
try {
|
|
33213
|
+
const { preset, entries, interval, features, threads, activeContext } = args2;
|
|
33214
|
+
const params = {};
|
|
33215
|
+
if (preset !== void 0) {
|
|
33216
|
+
params.preset = preset;
|
|
33217
|
+
} else {
|
|
33218
|
+
if (entries === void 0 || interval === void 0 || features === void 0 || threads === void 0) {
|
|
33219
|
+
throw new Error(
|
|
33220
|
+
"When no preset is given, entries, interval, features, and threads are all required."
|
|
33221
|
+
);
|
|
33222
|
+
}
|
|
33223
|
+
params.entries = entries;
|
|
33224
|
+
params.interval = interval;
|
|
33225
|
+
params.features = features;
|
|
33226
|
+
params.threads = threads;
|
|
33227
|
+
}
|
|
33228
|
+
if (activeContext !== void 0) {
|
|
33229
|
+
params.activeContext = activeContext;
|
|
33230
|
+
}
|
|
33231
|
+
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
33232
|
+
const firefox3 = await getFirefox2();
|
|
33233
|
+
checkProfilerSupported(firefox3);
|
|
33234
|
+
await firefox3.sendBiDiCommand("moz:profiler.start", params);
|
|
33235
|
+
return successResponse("Profiler started");
|
|
33236
|
+
} catch (error2) {
|
|
33237
|
+
return errorResponse(error2);
|
|
33238
|
+
}
|
|
33239
|
+
}
|
|
33240
|
+
async function handleProfilerStop(args2) {
|
|
33241
|
+
try {
|
|
33242
|
+
const { discard } = args2;
|
|
33243
|
+
const params = {};
|
|
33244
|
+
if (discard !== void 0) {
|
|
33245
|
+
params.discard = discard;
|
|
33246
|
+
}
|
|
33247
|
+
const { getFirefox: getFirefox2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
33248
|
+
const firefox3 = await getFirefox2();
|
|
33249
|
+
checkProfilerSupported(firefox3);
|
|
33250
|
+
const result = await firefox3.sendBiDiCommand("moz:profiler.stop", params);
|
|
33251
|
+
if (result.path) {
|
|
33252
|
+
return successResponse(`Profile saved to: ${result.path}`);
|
|
33253
|
+
}
|
|
33254
|
+
return successResponse("Profiler stopped. No profile was saved.");
|
|
33255
|
+
} catch (error2) {
|
|
33256
|
+
return errorResponse(error2);
|
|
33257
|
+
}
|
|
33258
|
+
}
|
|
33259
|
+
var MIN_FIREFOX_VERSION, VALID_PRESETS, profilerIsActiveTool, profilerStartTool, profilerStopTool;
|
|
33260
|
+
var init_profiler = __esm({
|
|
33261
|
+
"src/tools/profiler.ts"() {
|
|
33262
|
+
"use strict";
|
|
33263
|
+
init_response_helpers();
|
|
33264
|
+
init_version();
|
|
33265
|
+
MIN_FIREFOX_VERSION = "154.0";
|
|
33266
|
+
VALID_PRESETS = [
|
|
33267
|
+
"web-developer",
|
|
33268
|
+
"firefox-platform",
|
|
33269
|
+
"graphics",
|
|
33270
|
+
"media",
|
|
33271
|
+
"ml",
|
|
33272
|
+
"networking",
|
|
33273
|
+
"power",
|
|
33274
|
+
"debug"
|
|
33275
|
+
];
|
|
33276
|
+
profilerIsActiveTool = {
|
|
33277
|
+
name: "profiler_is_active",
|
|
33278
|
+
description: "Check whether the Firefox profiler is currently recording.",
|
|
33279
|
+
inputSchema: {
|
|
33280
|
+
type: "object",
|
|
33281
|
+
properties: {}
|
|
33282
|
+
}
|
|
33283
|
+
};
|
|
33284
|
+
profilerStartTool = {
|
|
33285
|
+
name: "profiler_start",
|
|
33286
|
+
description: `Start the Firefox profiler. Provide either a preset name or explicit recording options (entries, interval, features, threads). Cannot combine both. Valid presets: ${VALID_PRESETS.join(", ")}.`,
|
|
33287
|
+
inputSchema: {
|
|
33288
|
+
type: "object",
|
|
33289
|
+
properties: {
|
|
33290
|
+
preset: {
|
|
33291
|
+
type: "string",
|
|
33292
|
+
enum: VALID_PRESETS,
|
|
33293
|
+
description: "Profiler preset name. Cannot be combined with entries, interval, features, or threads."
|
|
33294
|
+
},
|
|
33295
|
+
entries: {
|
|
33296
|
+
type: "integer",
|
|
33297
|
+
description: "Number of entries to keep in the sampling buffer. Required when no preset is given."
|
|
33298
|
+
},
|
|
33299
|
+
interval: {
|
|
33300
|
+
type: "number",
|
|
33301
|
+
description: "Sampling interval in milliseconds. Required when no preset is given."
|
|
33302
|
+
},
|
|
33303
|
+
features: {
|
|
33304
|
+
type: "array",
|
|
33305
|
+
items: { type: "string" },
|
|
33306
|
+
description: "Profiler features to enable. Required when no preset is given."
|
|
33307
|
+
},
|
|
33308
|
+
threads: {
|
|
33309
|
+
type: "array",
|
|
33310
|
+
items: { type: "string" },
|
|
33311
|
+
description: "Thread names to profile. Required when no preset is given."
|
|
33312
|
+
},
|
|
33313
|
+
activeContext: {
|
|
33314
|
+
type: "string",
|
|
33315
|
+
description: "Id of the top-level navigable to mark as the active tab in the profile. Does not restrict profiling to that tab."
|
|
33316
|
+
}
|
|
33317
|
+
}
|
|
33318
|
+
}
|
|
33319
|
+
};
|
|
33320
|
+
profilerStopTool = {
|
|
33321
|
+
name: "profiler_stop",
|
|
33322
|
+
description: "Stop the Firefox profiler and save the recorded profile to a file in the downloads directory. Returns the path to the saved file, or null when nothing was saved.",
|
|
33323
|
+
inputSchema: {
|
|
33324
|
+
type: "object",
|
|
33325
|
+
properties: {
|
|
33326
|
+
discard: {
|
|
33327
|
+
type: "boolean",
|
|
33328
|
+
description: "If true, stop the profiler and discard the recording instead of saving it to disk. Defaults to false."
|
|
33329
|
+
}
|
|
33330
|
+
}
|
|
33331
|
+
}
|
|
33332
|
+
};
|
|
33333
|
+
}
|
|
33334
|
+
});
|
|
33335
|
+
|
|
32644
33336
|
// src/tools/index.ts
|
|
32645
33337
|
var init_tools = __esm({
|
|
32646
33338
|
"src/tools/index.ts"() {
|
|
@@ -32657,6 +33349,8 @@ var init_tools = __esm({
|
|
|
32657
33349
|
init_privileged_context();
|
|
32658
33350
|
init_firefox_prefs();
|
|
32659
33351
|
init_webextension();
|
|
33352
|
+
init_debugging2();
|
|
33353
|
+
init_profiler();
|
|
32660
33354
|
}
|
|
32661
33355
|
});
|
|
32662
33356
|
|
|
@@ -32675,9 +33369,9 @@ import { version as version2 } from "process";
|
|
|
32675
33369
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
32676
33370
|
import { resolve as resolve3 } from "path";
|
|
32677
33371
|
import { realpathSync } from "fs";
|
|
32678
|
-
function resetFirefox() {
|
|
33372
|
+
async function resetFirefox() {
|
|
32679
33373
|
if (firefox2) {
|
|
32680
|
-
firefox2.
|
|
33374
|
+
await firefox2.close();
|
|
32681
33375
|
firefox2 = null;
|
|
32682
33376
|
}
|
|
32683
33377
|
pendingWarning = null;
|
|
@@ -32698,7 +33392,7 @@ async function getFirefox() {
|
|
|
32698
33392
|
const isConnected = await firefox2.isConnected();
|
|
32699
33393
|
if (!isConnected) {
|
|
32700
33394
|
log("Firefox connection lost, reconnecting...");
|
|
32701
|
-
resetFirefox();
|
|
33395
|
+
await resetFirefox();
|
|
32702
33396
|
} else {
|
|
32703
33397
|
return firefox2;
|
|
32704
33398
|
}
|
|
@@ -32746,8 +33440,7 @@ async function getFirefox() {
|
|
|
32746
33440
|
pendingWarning = firefox2.getAndClearProfileWarning();
|
|
32747
33441
|
return firefox2;
|
|
32748
33442
|
} catch (error2) {
|
|
32749
|
-
await firefox2.close()
|
|
32750
|
-
});
|
|
33443
|
+
await firefox2.close();
|
|
32751
33444
|
firefox2 = null;
|
|
32752
33445
|
throw error2;
|
|
32753
33446
|
}
|
|
@@ -32767,6 +33460,9 @@ async function run(parseArgsFn, importMetaUrl) {
|
|
|
32767
33460
|
return;
|
|
32768
33461
|
}
|
|
32769
33462
|
args = parseArgsFn(SERVER_VERSION);
|
|
33463
|
+
if (args.logFile) {
|
|
33464
|
+
setupLogFile(args.logFile);
|
|
33465
|
+
}
|
|
32770
33466
|
const toolHandlers = new Map([
|
|
32771
33467
|
// Pages
|
|
32772
33468
|
["list_pages", handleListPages],
|
|
@@ -32806,8 +33502,21 @@ async function run(parseArgsFn, importMetaUrl) {
|
|
|
32806
33502
|
// WebExtensions (install/uninstall use standard BiDi, no privileged context required)
|
|
32807
33503
|
["install_extension", handleInstallExtension],
|
|
32808
33504
|
["uninstall_extension", handleUninstallExtension],
|
|
33505
|
+
// Profiler
|
|
33506
|
+
["profiler_is_active", handleProfilerIsActive],
|
|
33507
|
+
["profiler_start", handleProfilerStart],
|
|
33508
|
+
["profiler_stop", handleProfilerStop],
|
|
32809
33509
|
// Script evaluation — requires --enable-script
|
|
32810
33510
|
...args.enableScript ? [["evaluate_script", handleEvaluateScript]] : [],
|
|
33511
|
+
// Debugging tools — requires --enable-script
|
|
33512
|
+
...args.enableScript ? [
|
|
33513
|
+
["enable_debugger", handleEnableDebugger],
|
|
33514
|
+
["list_scripts", handleListScripts],
|
|
33515
|
+
["get_script_source", handleGetScriptSource],
|
|
33516
|
+
["set_logpoint", handleSetLogpoint],
|
|
33517
|
+
["remove_logpoint", handleRemoveLogpoint],
|
|
33518
|
+
["get_logpoint_results", handleGetLogpointResults]
|
|
33519
|
+
] : [],
|
|
32811
33520
|
// Privileged context tools — requires --enable-privileged-context
|
|
32812
33521
|
...args.enablePrivilegedContext ? [
|
|
32813
33522
|
["list_privileged_contexts", handleListPrivilegedContexts],
|
|
@@ -32848,8 +33557,20 @@ async function run(parseArgsFn, importMetaUrl) {
|
|
|
32848
33557
|
restartFirefoxTool,
|
|
32849
33558
|
installExtensionTool,
|
|
32850
33559
|
uninstallExtensionTool,
|
|
33560
|
+
profilerIsActiveTool,
|
|
33561
|
+
profilerStartTool,
|
|
33562
|
+
profilerStopTool,
|
|
32851
33563
|
// Script evaluation — requires --enable-script
|
|
32852
33564
|
...args.enableScript ? [evaluateScriptTool] : [],
|
|
33565
|
+
// Debugging tools — requires --enable-script
|
|
33566
|
+
...args.enableScript ? [
|
|
33567
|
+
enableDebuggerTool,
|
|
33568
|
+
listScriptsTool,
|
|
33569
|
+
getScriptSourceTool,
|
|
33570
|
+
setLogpointTool,
|
|
33571
|
+
removeLogpointTool,
|
|
33572
|
+
getLogpointResultsTool
|
|
33573
|
+
] : [],
|
|
32853
33574
|
// Privileged context tools — requires --enable-privileged-context
|
|
32854
33575
|
...args.enablePrivilegedContext ? [
|
|
32855
33576
|
listPrivilegedContextsTool,
|
|
@@ -32922,13 +33643,10 @@ async function run(parseArgsFn, importMetaUrl) {
|
|
|
32922
33643
|
log("Firefox DevTools MCP server running on stdio");
|
|
32923
33644
|
log("Ready to accept tool requests");
|
|
32924
33645
|
const cleanup = async () => {
|
|
32925
|
-
|
|
32926
|
-
try {
|
|
32927
|
-
await firefox2.close();
|
|
32928
|
-
} catch {
|
|
32929
|
-
}
|
|
32930
|
-
}
|
|
33646
|
+
await resetFirefox();
|
|
32931
33647
|
await server.close();
|
|
33648
|
+
await flushLogs().catch(() => {
|
|
33649
|
+
});
|
|
32932
33650
|
process.exit(0);
|
|
32933
33651
|
};
|
|
32934
33652
|
const onSignal = () => void cleanup();
|
|
@@ -33034,7 +33752,7 @@ var require_package = __commonJS({
|
|
|
33034
33752
|
var require_main = __commonJS({
|
|
33035
33753
|
"node_modules/dotenv/lib/main.js"(exports, module) {
|
|
33036
33754
|
"use strict";
|
|
33037
|
-
var
|
|
33755
|
+
var fs2 = __require("fs");
|
|
33038
33756
|
var path = __require("path");
|
|
33039
33757
|
var os = __require("os");
|
|
33040
33758
|
var crypto = __require("crypto");
|
|
@@ -33173,7 +33891,7 @@ var require_main = __commonJS({
|
|
|
33173
33891
|
if (options && options.path && options.path.length > 0) {
|
|
33174
33892
|
if (Array.isArray(options.path)) {
|
|
33175
33893
|
for (const filepath of options.path) {
|
|
33176
|
-
if (
|
|
33894
|
+
if (fs2.existsSync(filepath)) {
|
|
33177
33895
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
33178
33896
|
}
|
|
33179
33897
|
}
|
|
@@ -33183,7 +33901,7 @@ var require_main = __commonJS({
|
|
|
33183
33901
|
} else {
|
|
33184
33902
|
possibleVaultPath = path.resolve(process.cwd(), ".env.vault");
|
|
33185
33903
|
}
|
|
33186
|
-
if (
|
|
33904
|
+
if (fs2.existsSync(possibleVaultPath)) {
|
|
33187
33905
|
return possibleVaultPath;
|
|
33188
33906
|
}
|
|
33189
33907
|
return null;
|
|
@@ -33236,7 +33954,7 @@ var require_main = __commonJS({
|
|
|
33236
33954
|
const parsedAll = {};
|
|
33237
33955
|
for (const path2 of optionPaths) {
|
|
33238
33956
|
try {
|
|
33239
|
-
const parsed = DotenvModule.parse(
|
|
33957
|
+
const parsed = DotenvModule.parse(fs2.readFileSync(path2, { encoding }));
|
|
33240
33958
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
33241
33959
|
} catch (e) {
|
|
33242
33960
|
if (debug) {
|