v0.0.17 - Fix browser crash on target=_blank links (WebKit WindowFeatures assertion), MCP session recovery on browser restart, click_at tool for coordinate-based clicking
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"sovereign-browser": {
|
||||||
|
"url": "http://localhost:17777/mcp",
|
||||||
|
"type": "streamable-http",
|
||||||
|
"alwaysAllow": [
|
||||||
|
"login_status",
|
||||||
|
"snapshot",
|
||||||
|
"click",
|
||||||
|
"click_at",
|
||||||
|
"screenshot",
|
||||||
|
"login",
|
||||||
|
"logout",
|
||||||
|
"switch_identity",
|
||||||
|
"open",
|
||||||
|
"back",
|
||||||
|
"forward",
|
||||||
|
"reload",
|
||||||
|
"get_url",
|
||||||
|
"get_title",
|
||||||
|
"get_attr",
|
||||||
|
"get_value",
|
||||||
|
"get_count",
|
||||||
|
"get_box",
|
||||||
|
"get_styles",
|
||||||
|
"is_visible",
|
||||||
|
"is_enabled",
|
||||||
|
"is_checked",
|
||||||
|
"eval",
|
||||||
|
"fill",
|
||||||
|
"type",
|
||||||
|
"press",
|
||||||
|
"hover",
|
||||||
|
"focus",
|
||||||
|
"close",
|
||||||
|
"tab_list",
|
||||||
|
"tab_new",
|
||||||
|
"tab_switch",
|
||||||
|
"tab_close",
|
||||||
|
"wait",
|
||||||
|
"wait_for",
|
||||||
|
"screenshot_annotated",
|
||||||
|
"pdf",
|
||||||
|
"upload",
|
||||||
|
"state_load",
|
||||||
|
"get_text",
|
||||||
|
"get_html",
|
||||||
|
"scroll",
|
||||||
|
"dblclick",
|
||||||
|
"select",
|
||||||
|
"check",
|
||||||
|
"uncheck",
|
||||||
|
"scroll_into_view",
|
||||||
|
"insert_text",
|
||||||
|
"keydown",
|
||||||
|
"keyup",
|
||||||
|
"drag",
|
||||||
|
"close_all",
|
||||||
|
"find_role",
|
||||||
|
"find_label",
|
||||||
|
"find_placeholder",
|
||||||
|
"find_alt",
|
||||||
|
"find_title",
|
||||||
|
"find_testid",
|
||||||
|
"find_first",
|
||||||
|
"find_last",
|
||||||
|
"find_nth",
|
||||||
|
"wait_for_text",
|
||||||
|
"wait_for_url",
|
||||||
|
"wait_for_load",
|
||||||
|
"batch",
|
||||||
|
"cookies_get",
|
||||||
|
"cookies_set",
|
||||||
|
"cookies_clear",
|
||||||
|
"storage_local_get",
|
||||||
|
"storage_local_get_key",
|
||||||
|
"storage_local_set",
|
||||||
|
"storage_local_clear",
|
||||||
|
"storage_session_get",
|
||||||
|
"storage_session_get_key",
|
||||||
|
"storage_session_set",
|
||||||
|
"storage_session_clear",
|
||||||
|
"mouse_move",
|
||||||
|
"mouse_down",
|
||||||
|
"mouse_up",
|
||||||
|
"mouse_wheel",
|
||||||
|
"clipboard_read",
|
||||||
|
"clipboard_write",
|
||||||
|
"clipboard_copy",
|
||||||
|
"clipboard_paste",
|
||||||
|
"set_viewport",
|
||||||
|
"set_offline",
|
||||||
|
"set_headers",
|
||||||
|
"set_credentials",
|
||||||
|
"set_media",
|
||||||
|
"frame_switch",
|
||||||
|
"frame_main",
|
||||||
|
"dialog_accept",
|
||||||
|
"dialog_dismiss",
|
||||||
|
"dialog_status",
|
||||||
|
"console",
|
||||||
|
"errors",
|
||||||
|
"highlight",
|
||||||
|
"state_save"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
-11
@@ -697,17 +697,18 @@ static void on_mcp_request(SoupServer *server,
|
|||||||
if (sid != NULL) {
|
if (sid != NULL) {
|
||||||
session = session_lookup(sid);
|
session = session_lookup(sid);
|
||||||
if (session == NULL) {
|
if (session == NULL) {
|
||||||
/* Unknown or expired session. */
|
/* Unknown or expired session — create a new one and return
|
||||||
cJSON *err_resp = rpc_error(rpc_id, -32000, "Session not found or expired");
|
* the new session ID in the response header so the client
|
||||||
char *err_str = cJSON_PrintUnformatted(err_resp);
|
* can update its cached session ID. This handles browser
|
||||||
cJSON_Delete(err_resp);
|
* restarts gracefully without requiring the client to
|
||||||
char *sse = build_sse_response(err_str);
|
* re-initialize. */
|
||||||
free(err_str);
|
session = session_create();
|
||||||
soup_server_message_set_status(msg, 404, NULL);
|
SoupMessageHeaders *resp_hdrs =
|
||||||
soup_server_message_set_response(msg, "text/event-stream",
|
soup_server_message_get_response_headers(msg);
|
||||||
SOUP_MEMORY_TAKE, sse, strlen(sse));
|
soup_message_headers_append(resp_hdrs,
|
||||||
cJSON_Delete(request);
|
"Mcp-Session-Id", session->session_id);
|
||||||
return;
|
g_print("[mcp] Stale session '%s' — created new session '%s'\n",
|
||||||
|
sid, session->session_id);
|
||||||
}
|
}
|
||||||
session_touch(session);
|
session_touch(session);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+14
-13
@@ -656,21 +656,22 @@ static GtkWidget *on_create_webview(WebKitWebView *webview,
|
|||||||
WebKitURIRequest *request = webkit_navigation_action_get_request(action);
|
WebKitURIRequest *request = webkit_navigation_action_get_request(action);
|
||||||
const char *uri = webkit_uri_request_get_uri(request);
|
const char *uri = webkit_uri_request_get_uri(request);
|
||||||
|
|
||||||
/* Create a new tab with the requested URI. tab_manager_new_tab
|
/* When a page requests a new window (target="_blank"), WebKit fires
|
||||||
* creates the webview and loads the URL. We need to return the
|
* the "create" signal. We intercept it by opening the URI in a new
|
||||||
* webview widget, so we create the tab and then get its webview. */
|
* tab ourselves, then return NULL to tell WebKit we handled it.
|
||||||
int index = tab_manager_new_tab(uri);
|
*
|
||||||
if (index < 0) {
|
* Returning a webview here causes a crash in WebKit's
|
||||||
/* Max tabs reached — return a dummy webview. */
|
* std::optional<WindowFeatures> assertion because the returned
|
||||||
return GTK_WIDGET(webkit_web_view_new_with_context(g_ctx));
|
* webview doesn't have the expected window features set up.
|
||||||
|
* By returning NULL and handling the navigation ourselves, we
|
||||||
|
* avoid the crash entirely. */
|
||||||
|
if (uri && uri[0]) {
|
||||||
|
tab_manager_new_tab(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
tab_info_t *tab = tab_manager_get(index);
|
/* Return NULL to indicate we handled the creation ourselves.
|
||||||
if (tab && tab->webview) {
|
* WebKit will not proceed with the navigation in a new view. */
|
||||||
return GTK_WIDGET(tab->webview);
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
return GTK_WIDGET(webkit_web_view_new_with_context(g_ctx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *build_tab_label(tab_info_t *tab) {
|
static GtkWidget *build_tab_label(tab_info_t *tab) {
|
||||||
|
|||||||
+2
-2
@@ -11,9 +11,9 @@
|
|||||||
#ifndef SOVEREIGN_BROWSER_VERSION_H
|
#ifndef SOVEREIGN_BROWSER_VERSION_H
|
||||||
#define SOVEREIGN_BROWSER_VERSION_H
|
#define SOVEREIGN_BROWSER_VERSION_H
|
||||||
|
|
||||||
#define SB_VERSION "v0.0.16"
|
#define SB_VERSION "v0.0.17"
|
||||||
#define SB_VERSION_MAJOR 0
|
#define SB_VERSION_MAJOR 0
|
||||||
#define SB_VERSION_MINOR 0
|
#define SB_VERSION_MINOR 0
|
||||||
#define SB_VERSION_PATCH 16
|
#define SB_VERSION_PATCH 17
|
||||||
|
|
||||||
#endif /* SOVEREIGN_BROWSER_VERSION_H */
|
#endif /* SOVEREIGN_BROWSER_VERSION_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user