From 14be38dd16fa81e513b9e28b8423f93c706419ce Mon Sep 17 00:00:00 2001 From: Aaron Elijah Mars Date: Tue, 15 Jul 2025 17:43:08 +0200 Subject: [PATCH] safety mode --- opendia-extension/background.js | 21 ++++++++ opendia-extension/popup.html | 89 +++++++++++++++++++++++++++++++++ opendia-extension/popup.js | 23 +++++++++ 3 files changed, 133 insertions(+) diff --git a/opendia-extension/background.js b/opendia-extension/background.js index ae4c556..74bf409 100644 --- a/opendia-extension/background.js +++ b/opendia-extension/background.js @@ -5,6 +5,18 @@ let reconnectInterval = null; let reconnectAttempts = 0; let lastKnownPorts = { websocket: 5555, http: 5556 }; // Cache for port discovery +// Safety Mode configuration +let safetyModeEnabled = false; +const WRITE_EDIT_TOOLS = [ + 'element_click', + 'element_fill' +]; + +// Load safety mode state on startup +chrome.storage.local.get(['safetyMode'], (result) => { + safetyModeEnabled = result.safetyMode || false; +}); + // Port discovery function async function discoverServerPorts() { // Try common HTTP ports to find the server @@ -528,6 +540,11 @@ async function handleMCPRequest(message) { const { id, method, params } = message; try { + // Safety Mode check: Block write/edit tools if safety mode is enabled + if (safetyModeEnabled && WRITE_EDIT_TOOLS.includes(method)) { + throw new Error(`🛡️ Safety Mode is enabled. This tool (${method}) is blocked to prevent page modifications. To disable Safety Mode, open the OpenDia extension popup and toggle off "Safety Mode".`); + } + let result; switch (method) { @@ -1188,6 +1205,10 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { current: lastKnownPorts, websocketUrl: MCP_SERVER_URL }); + } else if (request.action === "setSafetyMode") { + safetyModeEnabled = request.enabled; + console.log(`🛡️ Safety Mode ${safetyModeEnabled ? 'ENABLED' : 'DISABLED'}`); + sendResponse({ success: true }); } else if (request.action === "test") { if (mcpSocket && mcpSocket.readyState === WebSocket.OPEN) { mcpSocket.send(JSON.stringify({ type: "test", timestamp: Date.now() })); diff --git a/opendia-extension/popup.html b/opendia-extension/popup.html index a466710..b9856b0 100644 --- a/opendia-extension/popup.html +++ b/opendia-extension/popup.html @@ -236,6 +236,80 @@ button:active { transform: translateY(0); } + + .safety-mode { + background: rgba(255, 255, 255, 0.6); + padding: 16px; + border-radius: 10px; + margin-bottom: 16px; + border: 1px solid rgba(255, 255, 255, 0.8); + backdrop-filter: blur(20px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + } + + .safety-row { + display: flex; + justify-content: space-between; + align-items: center; + } + + .safety-label { + color: #374151; + font-weight: 600; + font-size: 0.875rem; + } + + .safety-toggle { + position: relative; + display: inline-block; + width: 50px; + height: 24px; + } + + .safety-toggle input { + opacity: 0; + width: 0; + height: 0; + } + + .safety-slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #e5e7eb; + transition: 0.3s; + border-radius: 24px; + border: 1px solid rgba(0, 129, 247, 0.2); + } + + .safety-slider:before { + position: absolute; + content: ""; + height: 18px; + width: 18px; + left: 2px; + bottom: 2px; + background-color: white; + transition: 0.3s; + border-radius: 50%; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + } + + input:checked + .safety-slider { + background: linear-gradient(135deg, #0081F7, #1d4ed8); + border-color: rgba(0, 129, 247, 0.4); + } + + input:checked + .safety-slider:before { + transform: translateX(26px); + } + + .safety-slider:hover { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + } @@ -277,6 +351,21 @@ +
+
+ + Safety Mode + + When enabled, blocks write/edit tools: element_click, element_fill + + + +
+
+
diff --git a/opendia-extension/popup.js b/opendia-extension/popup.js index 2cb3ff9..4d4a9c2 100644 --- a/opendia-extension/popup.js +++ b/opendia-extension/popup.js @@ -100,6 +100,29 @@ document.getElementById("reconnectBtn").addEventListener("click", () => { }); +// Safety Mode Management +const safetyModeToggle = document.getElementById("safetyMode"); + +// Load safety mode state from storage +chrome.storage.local.get(['safetyMode'], (result) => { + const safetyEnabled = result.safetyMode || false; // Default to false (safety off) + safetyModeToggle.checked = safetyEnabled; +}); + +// Handle safety mode toggle changes +safetyModeToggle.addEventListener('change', () => { + const safetyEnabled = safetyModeToggle.checked; + + // Save to storage + chrome.storage.local.set({ safetyMode: safetyEnabled }); + + // Notify background script + chrome.runtime.sendMessage({ + action: "setSafetyMode", + enabled: safetyEnabled + }); +}); + // Listen for updates from background script chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.type === "statusUpdate") {