diff --git a/bin/muse-chat-api.py b/bin/muse-chat-api.py index b4c71a2..e61ecab 100755 --- a/bin/muse-chat-api.py +++ b/bin/muse-chat-api.py @@ -102,6 +102,10 @@ def check_approvals(ws): # Extract IP if present import re ips = re.findall(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b', d) + # Only block for IP-based permission dialogs. Dialogs without IPs + # are likely false positives (chat content, UI text) - don't block. + if not ips: + continue is_trusted = any(ip in TRUSTED_IPS for ip in ips) if is_trusted: # Auto-approve: click "Allow once" or "Allow" @@ -116,7 +120,7 @@ def check_approvals(ws): actions.append((d[:80], True, clicked)) else: actions.append((d[:80], False, "APPROVAL_NEEDED")) - + return actions def cmd_approvals(ws): @@ -207,26 +211,32 @@ def cmd_sidechat_use(ws, chat_id): print(f"Navigated to: {result}") def cmd_sidechat_main(ws): - """Navigate back to main chat by pressing the chat button.""" - # The chat button (not the sidebar search) properly refocuses Main Chat. + """Navigate back to main chat via Ctrl+J keyboard shortcut.""" + # Ctrl+J (the Chat button shortcut) properly refocuses Main Chat. + # More reliable than DOM scraping for buttons/text. # Do NOT navigate to https://muse.ai/ (landing page) - it restores the # last-viewed chat which may be a side chat. - js = ( - "(async()=>{" - # Find the chat button - it refocuses Main Chat when pressed - "const btns=[...document.querySelectorAll('button')];" - "const chatBtn=btns.find(b=>" - "b.textContent.includes('Open chat and side chats')||" - "b.getAttribute('aria-label')&&b.getAttribute('aria-label').toLowerCase().includes('chat')" - ");" - "if(!chatBtn)return 'NOBUTTON';" - "chatBtn.click();" - "await new Promise(r=>setTimeout(r,4000));" - "return window.location.href;" - "})()" - ) - result = ev(ws, js, True) - print(f"Back to main chat: {result}") + import json as _json + # Send Ctrl+J via Input.dispatchKeyEvent + ws.send(_json.dumps({ + "id": 10, "method": "Input.dispatchKeyEvent", + "params": {"type": "keyDown", "key": "j", "code": "KeyJ", + "ctrlKey": True, "modifiers": 2} + })) + _json.loads(ws.recv()) + ws.send(_json.dumps({ + "id": 11, "method": "Input.dispatchKeyEvent", + "params": {"type": "keyUp", "key": "j", "code": "KeyJ", + "ctrlKey": True, "modifiers": 2} + })) + _json.loads(ws.recv()) + time.sleep(4) + # Get current URL to confirm navigation + ws.send(_json.dumps({"id": 12, "method": "Runtime.evaluate", + "params": {"expression": "window.location.href"}})) + resp = _json.loads(ws.recv()) + url = resp.get("result", {}).get("result", {}).get("value", "unknown") + print(f"Back to main chat: {url}") def cmd_sidechat_list(ws): """List side chats via DOM."""