mirror of
https://github.com/aaronjmars/opendia.git
synced 2025-12-29 16:16:00 +00:00
safety mode
This commit is contained in:
parent
aa78576ad7
commit
14be38dd16
@ -5,6 +5,18 @@ let reconnectInterval = null;
|
|||||||
let reconnectAttempts = 0;
|
let reconnectAttempts = 0;
|
||||||
let lastKnownPorts = { websocket: 5555, http: 5556 }; // Cache for port discovery
|
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
|
// Port discovery function
|
||||||
async function discoverServerPorts() {
|
async function discoverServerPorts() {
|
||||||
// Try common HTTP ports to find the server
|
// Try common HTTP ports to find the server
|
||||||
@ -528,6 +540,11 @@ async function handleMCPRequest(message) {
|
|||||||
const { id, method, params } = message;
|
const { id, method, params } = message;
|
||||||
|
|
||||||
try {
|
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;
|
let result;
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
@ -1188,6 +1205,10 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
current: lastKnownPorts,
|
current: lastKnownPorts,
|
||||||
websocketUrl: MCP_SERVER_URL
|
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") {
|
} else if (request.action === "test") {
|
||||||
if (mcpSocket && mcpSocket.readyState === WebSocket.OPEN) {
|
if (mcpSocket && mcpSocket.readyState === WebSocket.OPEN) {
|
||||||
mcpSocket.send(JSON.stringify({ type: "test", timestamp: Date.now() }));
|
mcpSocket.send(JSON.stringify({ type: "test", timestamp: Date.now() }));
|
||||||
|
|||||||
@ -236,6 +236,80 @@
|
|||||||
button:active {
|
button:active {
|
||||||
transform: translateY(0);
|
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);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -277,6 +351,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="safety-mode">
|
||||||
|
<div class="safety-row">
|
||||||
|
<span class="safety-label tooltip">
|
||||||
|
Safety Mode
|
||||||
|
<span class="tooltip-content">
|
||||||
|
When enabled, blocks write/edit tools: element_click, element_fill
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<label class="safety-toggle">
|
||||||
|
<input type="checkbox" id="safetyMode">
|
||||||
|
<span class="safety-slider"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button id="reconnectBtn">Reconnect</button>
|
<button id="reconnectBtn">Reconnect</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -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
|
// Listen for updates from background script
|
||||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
if (message.type === "statusUpdate") {
|
if (message.type === "statusUpdate") {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user