@electron-memory/monitor 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -206,6 +206,8 @@ interface MonitorConfig {
206
206
  height: number;
207
207
  /** 是否置顶,默认 false */
208
208
  alwaysOnTop: boolean;
209
+ /** 打开看板时是否自动打开 DevTools,默认 false;为 true 或环境变量 LAUNCHER_MEMORY_MONITOR_DEVTOOLS=1 时开启 */
210
+ openDevToolsOnStart: boolean;
209
211
  };
210
212
  /** 给窗口进程打标签,方便识别 */
211
213
  processLabels: Record<string, string>;
@@ -481,6 +483,12 @@ declare class ElectronMemoryMonitor extends EventEmitter {
481
483
  private mergeConfig;
482
484
  }
483
485
 
486
+ /**
487
+ * 必须在 app.on('ready') 之前调用(与 new ElectronMemoryMonitor 同文件顶部或更早)。
488
+ * 由 ElectronMemoryMonitor 在启用时于构造函数内调用。
489
+ */
490
+ declare function registerDashboardSchemePrivileged(): void;
491
+
484
492
  /**
485
493
  * IPC 通道常量定义
486
494
  * 所有通道以 'emm:' 为前缀,避免与业务 IPC 冲突
@@ -507,4 +515,4 @@ declare const IPC_CHANNELS: {
507
515
  readonly RENDERER_REQUEST: "emm:renderer:request";
508
516
  };
509
517
 
510
- export { type AnomalyCategory, type AnomalyEvent, type AnomalyRule, type AnomalySeverity, type CompareReport, ElectronMemoryMonitor, type EventMark, type GCResult, IPC_CHANNELS, type Improvement, type MemorySnapshot, type MetricDiff, type MetricSummary, type MonitorConfig, type ProcessMemoryInfo, type Regression, type RendererV8Detail, type SessionIndex, type SessionReport, type Suggestion, type SystemMemoryInfo, type TestSession, type TrendInfo, type V8HeapDetailStats, type V8HeapSpaceInfo, type V8HeapStats };
518
+ export { type AnomalyCategory, type AnomalyEvent, type AnomalyRule, type AnomalySeverity, type CompareReport, ElectronMemoryMonitor, type EventMark, type GCResult, IPC_CHANNELS, type Improvement, type MemorySnapshot, type MetricDiff, type MetricSummary, type MonitorConfig, type ProcessMemoryInfo, type Regression, type RendererV8Detail, type SessionIndex, type SessionReport, type Suggestion, type SystemMemoryInfo, type TestSession, type TrendInfo, type V8HeapDetailStats, type V8HeapSpaceInfo, type V8HeapStats, registerDashboardSchemePrivileged };
package/dist/index.d.ts CHANGED
@@ -206,6 +206,8 @@ interface MonitorConfig {
206
206
  height: number;
207
207
  /** 是否置顶,默认 false */
208
208
  alwaysOnTop: boolean;
209
+ /** 打开看板时是否自动打开 DevTools,默认 false;为 true 或环境变量 LAUNCHER_MEMORY_MONITOR_DEVTOOLS=1 时开启 */
210
+ openDevToolsOnStart: boolean;
209
211
  };
210
212
  /** 给窗口进程打标签,方便识别 */
211
213
  processLabels: Record<string, string>;
@@ -481,6 +483,12 @@ declare class ElectronMemoryMonitor extends EventEmitter {
481
483
  private mergeConfig;
482
484
  }
483
485
 
486
+ /**
487
+ * 必须在 app.on('ready') 之前调用(与 new ElectronMemoryMonitor 同文件顶部或更早)。
488
+ * 由 ElectronMemoryMonitor 在启用时于构造函数内调用。
489
+ */
490
+ declare function registerDashboardSchemePrivileged(): void;
491
+
484
492
  /**
485
493
  * IPC 通道常量定义
486
494
  * 所有通道以 'emm:' 为前缀,避免与业务 IPC 冲突
@@ -507,4 +515,4 @@ declare const IPC_CHANNELS: {
507
515
  readonly RENDERER_REQUEST: "emm:renderer:request";
508
516
  };
509
517
 
510
- export { type AnomalyCategory, type AnomalyEvent, type AnomalyRule, type AnomalySeverity, type CompareReport, ElectronMemoryMonitor, type EventMark, type GCResult, IPC_CHANNELS, type Improvement, type MemorySnapshot, type MetricDiff, type MetricSummary, type MonitorConfig, type ProcessMemoryInfo, type Regression, type RendererV8Detail, type SessionIndex, type SessionReport, type Suggestion, type SystemMemoryInfo, type TestSession, type TrendInfo, type V8HeapDetailStats, type V8HeapSpaceInfo, type V8HeapStats };
518
+ export { type AnomalyCategory, type AnomalyEvent, type AnomalyRule, type AnomalySeverity, type CompareReport, ElectronMemoryMonitor, type EventMark, type GCResult, IPC_CHANNELS, type Improvement, type MemorySnapshot, type MetricDiff, type MetricSummary, type MonitorConfig, type ProcessMemoryInfo, type Regression, type RendererV8Detail, type SessionIndex, type SessionReport, type Suggestion, type SystemMemoryInfo, type TestSession, type TrendInfo, type V8HeapDetailStats, type V8HeapSpaceInfo, type V8HeapStats, registerDashboardSchemePrivileged };
package/dist/index.js CHANGED
@@ -31,13 +31,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
33
  ElectronMemoryMonitor: () => ElectronMemoryMonitor,
34
- IPC_CHANNELS: () => IPC_CHANNELS
34
+ IPC_CHANNELS: () => IPC_CHANNELS,
35
+ registerDashboardSchemePrivileged: () => registerDashboardSchemePrivileged
35
36
  });
36
37
  module.exports = __toCommonJS(src_exports);
37
38
 
38
39
  // src/core/monitor.ts
39
- var import_electron4 = require("electron");
40
- var path3 = __toESM(require("path"));
40
+ var import_electron5 = require("electron");
41
+ var path4 = __toESM(require("path"));
41
42
  var v82 = __toESM(require("v8"));
42
43
  var import_events3 = require("events");
43
44
 
@@ -1106,8 +1107,150 @@ var Analyzer = class {
1106
1107
  };
1107
1108
 
1108
1109
  // src/core/dashboard.ts
1110
+ var import_electron3 = require("electron");
1111
+ var path3 = __toESM(require("path"));
1112
+
1113
+ // src/core/dashboard-protocol.ts
1109
1114
  var import_electron2 = require("electron");
1115
+ var import_promises = require("fs/promises");
1110
1116
  var path2 = __toESM(require("path"));
1117
+ var SCHEME = "emm-dashboard";
1118
+ var privilegedRegistered = false;
1119
+ var handlerRegistered = false;
1120
+ var MIME_BY_EXT = {
1121
+ ".html": "text/html; charset=utf-8",
1122
+ ".js": "text/javascript; charset=utf-8",
1123
+ ".mjs": "text/javascript; charset=utf-8",
1124
+ ".css": "text/css; charset=utf-8",
1125
+ ".json": "application/json",
1126
+ ".map": "application/json",
1127
+ ".svg": "image/svg+xml",
1128
+ ".png": "image/png",
1129
+ ".jpg": "image/jpeg",
1130
+ ".jpeg": "image/jpeg",
1131
+ ".gif": "image/gif",
1132
+ ".webp": "image/webp",
1133
+ ".ico": "image/x-icon",
1134
+ ".woff": "font/woff",
1135
+ ".woff2": "font/woff2",
1136
+ ".ttf": "font/ttf",
1137
+ ".txt": "text/plain; charset=utf-8"
1138
+ };
1139
+ function isPathInsideRoot(filePath, root) {
1140
+ const f = path2.resolve(filePath);
1141
+ const r = path2.resolve(root);
1142
+ if (f === r) {
1143
+ return true;
1144
+ }
1145
+ const sep2 = r.endsWith(path2.sep) ? r : `${r}${path2.sep}`;
1146
+ return f.startsWith(sep2);
1147
+ }
1148
+ function registerDashboardSchemePrivileged() {
1149
+ if (privilegedRegistered) {
1150
+ return;
1151
+ }
1152
+ privilegedRegistered = true;
1153
+ import_electron2.protocol.registerSchemesAsPrivileged([
1154
+ {
1155
+ scheme: SCHEME,
1156
+ privileges: {
1157
+ standard: true,
1158
+ secure: true,
1159
+ supportFetchAPI: true,
1160
+ corsEnabled: true,
1161
+ stream: true
1162
+ }
1163
+ }
1164
+ ]);
1165
+ }
1166
+ function ensureDashboardProtocolHandler(uiRoot) {
1167
+ if (handlerRegistered) {
1168
+ return;
1169
+ }
1170
+ if (!import_electron2.app.isReady()) {
1171
+ throw new Error(
1172
+ "[@electron-memory/monitor] ensureDashboardProtocolHandler: app must be ready before opening dashboard"
1173
+ );
1174
+ }
1175
+ handlerRegistered = true;
1176
+ const base = path2.resolve(uiRoot);
1177
+ import_electron2.protocol.handle(SCHEME, async (request) => {
1178
+ try {
1179
+ const { pathname } = new URL(request.url);
1180
+ let rel = pathname.startsWith("/") ? pathname.slice(1) : pathname;
1181
+ if (!rel) {
1182
+ rel = "index.html";
1183
+ }
1184
+ const filePath = path2.resolve(path2.join(base, rel));
1185
+ if (!isPathInsideRoot(filePath, base)) {
1186
+ return new Response("Forbidden", { status: 403 });
1187
+ }
1188
+ const body = await (0, import_promises.readFile)(filePath);
1189
+ const ext = path2.extname(filePath).toLowerCase();
1190
+ const mime = MIME_BY_EXT[ext] || "application/octet-stream";
1191
+ return new Response(body, {
1192
+ status: 200,
1193
+ headers: {
1194
+ "Content-Type": mime,
1195
+ "Cache-Control": "no-store"
1196
+ }
1197
+ });
1198
+ } catch (err) {
1199
+ const msg = err instanceof Error ? err.message : String(err);
1200
+ return new Response(msg, { status: 404 });
1201
+ }
1202
+ });
1203
+ }
1204
+ function getDashboardPageURL() {
1205
+ return `${SCHEME}://electron/index.html`;
1206
+ }
1207
+
1208
+ // src/core/dashboard-window-hooks.ts
1209
+ function shouldOpenDevToolsShortcut(input) {
1210
+ if (input.type !== "keyDown") {
1211
+ return false;
1212
+ }
1213
+ if (input.key === "F12") {
1214
+ return true;
1215
+ }
1216
+ const k = input.key.toLowerCase();
1217
+ if (k !== "i") {
1218
+ return false;
1219
+ }
1220
+ if (input.control && input.shift) {
1221
+ return true;
1222
+ }
1223
+ if (process.platform === "darwin" && input.meta && input.alt) {
1224
+ return true;
1225
+ }
1226
+ return false;
1227
+ }
1228
+ function attachDashboardWindowHooks(win, options) {
1229
+ const wc = win.webContents;
1230
+ wc.on("before-input-event", (event, input) => {
1231
+ if (!shouldOpenDevToolsShortcut(input)) {
1232
+ return;
1233
+ }
1234
+ event.preventDefault();
1235
+ if (wc.isDevToolsOpened()) {
1236
+ wc.closeDevTools();
1237
+ } else {
1238
+ wc.openDevTools({ mode: "detach" });
1239
+ }
1240
+ });
1241
+ wc.on("did-fail-load", (_e, code, desc, url) => {
1242
+ console.error("[@electron-memory/monitor] dashboard did-fail-load", code, desc, url);
1243
+ });
1244
+ let autoOpened = false;
1245
+ wc.on("did-finish-load", () => {
1246
+ if (options.openDevToolsOnStart && !autoOpened) {
1247
+ autoOpened = true;
1248
+ wc.openDevTools({ mode: "detach" });
1249
+ }
1250
+ });
1251
+ }
1252
+
1253
+ // src/core/dashboard.ts
1111
1254
  var DashboardManager = class {
1112
1255
  constructor(config) {
1113
1256
  this.window = null;
@@ -1130,8 +1273,8 @@ var DashboardManager = class {
1130
1273
  this.window.focus();
1131
1274
  return;
1132
1275
  }
1133
- const preloadPath = path2.join(__dirname, "dashboard-preload.js");
1134
- this.window = new import_electron2.BrowserWindow({
1276
+ const preloadPath = path3.join(__dirname, "dashboard-preload.js");
1277
+ this.window = new import_electron3.BrowserWindow({
1135
1278
  width: this.config.dashboard.width,
1136
1279
  height: this.config.dashboard.height,
1137
1280
  title: "Electron Memory Monitor",
@@ -1139,11 +1282,16 @@ var DashboardManager = class {
1139
1282
  webPreferences: {
1140
1283
  preload: preloadPath,
1141
1284
  contextIsolation: true,
1142
- nodeIntegration: false
1285
+ nodeIntegration: false,
1286
+ devTools: true
1143
1287
  }
1144
1288
  });
1145
- const uiPath = path2.join(__dirname, "ui", "index.html");
1146
- this.window.loadFile(uiPath);
1289
+ attachDashboardWindowHooks(this.window, {
1290
+ openDevToolsOnStart: this.config.dashboard.openDevToolsOnStart
1291
+ });
1292
+ const uiRoot = path3.join(__dirname, "ui");
1293
+ ensureDashboardProtocolHandler(uiRoot);
1294
+ this.window.loadURL(getDashboardPageURL());
1147
1295
  this.window.on("closed", () => {
1148
1296
  this.window = null;
1149
1297
  });
@@ -1165,7 +1313,7 @@ var DashboardManager = class {
1165
1313
  };
1166
1314
 
1167
1315
  // src/ipc/main-handler.ts
1168
- var import_electron3 = require("electron");
1316
+ var import_electron4 = require("electron");
1169
1317
 
1170
1318
  // src/ipc/channels.ts
1171
1319
  var IPC_CHANNELS = {
@@ -1203,49 +1351,49 @@ var IPCMainHandler = class {
1203
1351
  }
1204
1352
  /** 注册所有 IPC handlers */
1205
1353
  register() {
1206
- import_electron3.ipcMain.handle(IPC_CHANNELS.SESSION_START, (_event, args) => {
1354
+ import_electron4.ipcMain.handle(IPC_CHANNELS.SESSION_START, (_event, args) => {
1207
1355
  return this.monitor.startSession(args.label, args.description);
1208
1356
  });
1209
- import_electron3.ipcMain.handle(IPC_CHANNELS.SESSION_STOP, async () => {
1357
+ import_electron4.ipcMain.handle(IPC_CHANNELS.SESSION_STOP, async () => {
1210
1358
  return this.monitor.stopSession();
1211
1359
  });
1212
- import_electron3.ipcMain.handle(IPC_CHANNELS.SESSION_LIST, async () => {
1360
+ import_electron4.ipcMain.handle(IPC_CHANNELS.SESSION_LIST, async () => {
1213
1361
  return this.monitor.getSessions();
1214
1362
  });
1215
- import_electron3.ipcMain.handle(IPC_CHANNELS.SESSION_REPORT, async (_event, sessionId) => {
1363
+ import_electron4.ipcMain.handle(IPC_CHANNELS.SESSION_REPORT, async (_event, sessionId) => {
1216
1364
  return this.monitor.getSessionReport(sessionId);
1217
1365
  });
1218
- import_electron3.ipcMain.handle(IPC_CHANNELS.SESSION_COMPARE, async (_event, args) => {
1366
+ import_electron4.ipcMain.handle(IPC_CHANNELS.SESSION_COMPARE, async (_event, args) => {
1219
1367
  return this.monitor.compareSessions(args.baseId, args.targetId);
1220
1368
  });
1221
- import_electron3.ipcMain.handle(IPC_CHANNELS.SESSION_SNAPSHOTS, async (_event, args) => {
1369
+ import_electron4.ipcMain.handle(IPC_CHANNELS.SESSION_SNAPSHOTS, async (_event, args) => {
1222
1370
  return this.monitor.getSessionSnapshots(args.sessionId, args.startTime, args.endTime, args.maxPoints);
1223
1371
  });
1224
- import_electron3.ipcMain.handle(IPC_CHANNELS.TRIGGER_GC, async () => {
1372
+ import_electron4.ipcMain.handle(IPC_CHANNELS.TRIGGER_GC, async () => {
1225
1373
  return this.monitor.triggerGC();
1226
1374
  });
1227
- import_electron3.ipcMain.handle(IPC_CHANNELS.HEAP_SNAPSHOT, async (_event, filePath) => {
1375
+ import_electron4.ipcMain.handle(IPC_CHANNELS.HEAP_SNAPSHOT, async (_event, filePath) => {
1228
1376
  return this.monitor.takeHeapSnapshot(filePath);
1229
1377
  });
1230
- import_electron3.ipcMain.handle(IPC_CHANNELS.MARK, (_event, args) => {
1378
+ import_electron4.ipcMain.handle(IPC_CHANNELS.MARK, (_event, args) => {
1231
1379
  this.monitor.mark(args.label, args.metadata);
1232
1380
  });
1233
- import_electron3.ipcMain.handle(IPC_CHANNELS.GET_CONFIG, () => {
1381
+ import_electron4.ipcMain.handle(IPC_CHANNELS.GET_CONFIG, () => {
1234
1382
  return this.monitor.getConfig();
1235
1383
  });
1236
- import_electron3.ipcMain.handle(IPC_CHANNELS.GET_SESSIONS, async () => {
1384
+ import_electron4.ipcMain.handle(IPC_CHANNELS.GET_SESSIONS, async () => {
1237
1385
  return this.monitor.getSessions();
1238
1386
  });
1239
- import_electron3.ipcMain.handle(IPC_CHANNELS.SESSION_EXPORT, async (_event, sessionId) => {
1387
+ import_electron4.ipcMain.handle(IPC_CHANNELS.SESSION_EXPORT, async (_event, sessionId) => {
1240
1388
  return this.monitor.exportSession(sessionId);
1241
1389
  });
1242
- import_electron3.ipcMain.handle(IPC_CHANNELS.SESSION_IMPORT, async () => {
1390
+ import_electron4.ipcMain.handle(IPC_CHANNELS.SESSION_IMPORT, async () => {
1243
1391
  return this.monitor.importSession();
1244
1392
  });
1245
- import_electron3.ipcMain.handle(IPC_CHANNELS.SESSION_DELETE, async (_event, sessionId) => {
1393
+ import_electron4.ipcMain.handle(IPC_CHANNELS.SESSION_DELETE, async (_event, sessionId) => {
1246
1394
  return this.monitor.deleteSession(sessionId);
1247
1395
  });
1248
- import_electron3.ipcMain.on(IPC_CHANNELS.RENDERER_REPORT, (_event, detail) => {
1396
+ import_electron4.ipcMain.on(IPC_CHANNELS.RENDERER_REPORT, (_event, detail) => {
1249
1397
  this.monitor.updateRendererDetail(detail);
1250
1398
  });
1251
1399
  }
@@ -1265,8 +1413,8 @@ var IPCMainHandler = class {
1265
1413
  unregister() {
1266
1414
  const channels = Object.values(IPC_CHANNELS);
1267
1415
  for (const channel of channels) {
1268
- import_electron3.ipcMain.removeHandler(channel);
1269
- import_electron3.ipcMain.removeAllListeners(channel);
1416
+ import_electron4.ipcMain.removeHandler(channel);
1417
+ import_electron4.ipcMain.removeAllListeners(channel);
1270
1418
  }
1271
1419
  }
1272
1420
  };
@@ -1294,7 +1442,8 @@ var DEFAULT_CONFIG = {
1294
1442
  dashboard: {
1295
1443
  width: 1400,
1296
1444
  height: 900,
1297
- alwaysOnTop: false
1445
+ alwaysOnTop: false,
1446
+ openDevToolsOnStart: false
1298
1447
  },
1299
1448
  processLabels: {}
1300
1449
  };
@@ -1313,6 +1462,7 @@ var ElectronMemoryMonitor = class extends import_events3.EventEmitter {
1313
1462
  this.dashboard = null;
1314
1463
  return;
1315
1464
  }
1465
+ registerDashboardSchemePrivileged();
1316
1466
  this.collector = new MemoryCollector(this.config);
1317
1467
  this.anomalyDetector = new AnomalyDetector(this.config);
1318
1468
  this.analyzer = new Analyzer();
@@ -1325,10 +1475,10 @@ var ElectronMemoryMonitor = class extends import_events3.EventEmitter {
1325
1475
  /** 启动监控 */
1326
1476
  async start() {
1327
1477
  if (!this.config.enabled || this.started) return;
1328
- if (!import_electron4.app.isReady()) {
1329
- await import_electron4.app.whenReady();
1478
+ if (!import_electron5.app.isReady()) {
1479
+ await import_electron5.app.whenReady();
1330
1480
  }
1331
- const storageDir = this.config.storage.directory || path3.join(import_electron4.app.getPath("userData"), "memory-monitor");
1481
+ const storageDir = this.config.storage.directory || path4.join(import_electron5.app.getPath("userData"), "memory-monitor");
1332
1482
  this.persister = new DataPersister(this.config, storageDir);
1333
1483
  this.sessionManager = new SessionManager(this.persister);
1334
1484
  this.ipcHandler = new IPCMainHandler(this);
@@ -1400,7 +1550,7 @@ var ElectronMemoryMonitor = class extends import_events3.EventEmitter {
1400
1550
  anomalies,
1401
1551
  completedSession.dataFile
1402
1552
  );
1403
- const reportPath = path3.join(this.persister.getStorageDir(), completedSession.id, "report.json");
1553
+ const reportPath = path4.join(this.persister.getStorageDir(), completedSession.id, "report.json");
1404
1554
  const fs2 = await import("fs");
1405
1555
  fs2.writeFileSync(reportPath, JSON.stringify(report, null, 2), "utf-8");
1406
1556
  this.emit("session-end", report);
@@ -1430,7 +1580,7 @@ var ElectronMemoryMonitor = class extends import_events3.EventEmitter {
1430
1580
  /** 获取指定会话报告 */
1431
1581
  async getSessionReport(sessionId) {
1432
1582
  const fs2 = await import("fs");
1433
- const reportPath = path3.join(this.persister.getStorageDir(), sessionId, "report.json");
1583
+ const reportPath = path4.join(this.persister.getStorageDir(), sessionId, "report.json");
1434
1584
  try {
1435
1585
  const content = fs2.readFileSync(reportPath, "utf-8");
1436
1586
  return JSON.parse(content);
@@ -1561,7 +1711,7 @@ var ElectronMemoryMonitor = class extends import_events3.EventEmitter {
1561
1711
  } catch {
1562
1712
  }
1563
1713
  }
1564
- await new Promise((resolve) => setTimeout(resolve, 100));
1714
+ await new Promise((resolve2) => setTimeout(resolve2, 100));
1565
1715
  const afterMem = process.memoryUsage();
1566
1716
  const freed = beforeMem.heapUsed - afterMem.heapUsed;
1567
1717
  return {
@@ -1574,7 +1724,7 @@ var ElectronMemoryMonitor = class extends import_events3.EventEmitter {
1574
1724
  }
1575
1725
  /** 导出堆快照 */
1576
1726
  async takeHeapSnapshot(filePath) {
1577
- const snapshotPath = filePath || path3.join(
1727
+ const snapshotPath = filePath || path4.join(
1578
1728
  this.persister.getStorageDir(),
1579
1729
  `heap-${Date.now()}.heapsnapshot`
1580
1730
  );
@@ -1609,7 +1759,15 @@ var ElectronMemoryMonitor = class extends import_events3.EventEmitter {
1609
1759
  this.emit("snapshot", snapshot);
1610
1760
  }
1611
1761
  mergeConfig(userConfig) {
1612
- if (!userConfig) return { ...DEFAULT_CONFIG };
1762
+ if (!userConfig) {
1763
+ return {
1764
+ ...DEFAULT_CONFIG,
1765
+ dashboard: {
1766
+ ...DEFAULT_CONFIG.dashboard,
1767
+ openDevToolsOnStart: process.env.LAUNCHER_MEMORY_MONITOR_DEVTOOLS === "1"
1768
+ }
1769
+ };
1770
+ }
1613
1771
  return {
1614
1772
  ...DEFAULT_CONFIG,
1615
1773
  ...userConfig,
@@ -1623,7 +1781,8 @@ var ElectronMemoryMonitor = class extends import_events3.EventEmitter {
1623
1781
  },
1624
1782
  dashboard: {
1625
1783
  ...DEFAULT_CONFIG.dashboard,
1626
- ...userConfig.dashboard || {}
1784
+ ...userConfig.dashboard || {},
1785
+ openDevToolsOnStart: userConfig.dashboard?.openDevToolsOnStart !== void 0 ? userConfig.dashboard.openDevToolsOnStart : process.env.LAUNCHER_MEMORY_MONITOR_DEVTOOLS === "1"
1627
1786
  },
1628
1787
  processLabels: {
1629
1788
  ...DEFAULT_CONFIG.processLabels,
@@ -1635,6 +1794,7 @@ var ElectronMemoryMonitor = class extends import_events3.EventEmitter {
1635
1794
  // Annotate the CommonJS export names for ESM import in node:
1636
1795
  0 && (module.exports = {
1637
1796
  ElectronMemoryMonitor,
1638
- IPC_CHANNELS
1797
+ IPC_CHANNELS,
1798
+ registerDashboardSchemePrivileged
1639
1799
  });
1640
1800
  //# sourceMappingURL=index.js.map