@quanta-intellect/vessel-browser 0.1.25 → 0.1.26
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/README.md +6 -17
- package/out/main/index.js +210 -101
- package/out/preload/index.js +2 -0
- package/out/renderer/assets/{index-BynCvURs.css → index-DP2yMHwF.css} +67 -0
- package/out/renderer/assets/{index-32axMD1q.js → index-v71lXiVB.js} +656 -458
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
package/out/main/index.js
CHANGED
|
@@ -2450,6 +2450,7 @@ const Channels = {
|
|
|
2450
2450
|
PREMIUM_CHECKOUT: "premium:checkout",
|
|
2451
2451
|
PREMIUM_PORTAL: "premium:portal",
|
|
2452
2452
|
PREMIUM_RESET: "premium:reset",
|
|
2453
|
+
PREMIUM_TRACK_CONTEXT: "premium:track-context",
|
|
2453
2454
|
PREMIUM_UPDATE: "premium:update",
|
|
2454
2455
|
// Agent Credential Vault
|
|
2455
2456
|
VAULT_LIST: "vault:list",
|
|
@@ -3471,6 +3472,9 @@ function stopBackgroundRevalidation() {
|
|
|
3471
3472
|
revalidationTimer = null;
|
|
3472
3473
|
}
|
|
3473
3474
|
}
|
|
3475
|
+
function isPremiumActiveState(state2) {
|
|
3476
|
+
return state2.status === "active" || state2.status === "trialing";
|
|
3477
|
+
}
|
|
3474
3478
|
const POSTHOG_API_KEY = process.env.POSTHOG_API_KEY || "phc_OMeM3P5cxJwl14lOKxYad0Yre52xvjNfkLEFnPtXyM";
|
|
3475
3479
|
const POSTHOG_HOST = process.env.POSTHOG_HOST || "https://us.i.posthog.com";
|
|
3476
3480
|
const BATCH_INTERVAL_MS = 6e4;
|
|
@@ -13743,6 +13747,33 @@ async function requestConsent(request) {
|
|
|
13743
13747
|
}
|
|
13744
13748
|
let httpServer = null;
|
|
13745
13749
|
let mcpAuthToken = null;
|
|
13750
|
+
const MCP_AUTH_FILENAME = "mcp-auth.json";
|
|
13751
|
+
function getMcpAuthFilePath() {
|
|
13752
|
+
const configDir = process.env.VESSEL_CONFIG_DIR || path$1.join(
|
|
13753
|
+
process.env.XDG_CONFIG_HOME || path$1.join(os.homedir(), ".config"),
|
|
13754
|
+
"vessel"
|
|
13755
|
+
);
|
|
13756
|
+
return path$1.join(configDir, MCP_AUTH_FILENAME);
|
|
13757
|
+
}
|
|
13758
|
+
function writeMcpAuthFile(endpoint, token) {
|
|
13759
|
+
try {
|
|
13760
|
+
const filePath = getMcpAuthFilePath();
|
|
13761
|
+
fs$1.mkdirSync(path$1.dirname(filePath), { recursive: true });
|
|
13762
|
+
fs$1.writeFileSync(
|
|
13763
|
+
filePath,
|
|
13764
|
+
JSON.stringify({ endpoint, token, pid: process.pid }, null, 2) + "\n",
|
|
13765
|
+
{ mode: 384 }
|
|
13766
|
+
);
|
|
13767
|
+
} catch (err) {
|
|
13768
|
+
console.warn("[Vessel MCP] Failed to write auth file:", err);
|
|
13769
|
+
}
|
|
13770
|
+
}
|
|
13771
|
+
function clearMcpAuthFile() {
|
|
13772
|
+
try {
|
|
13773
|
+
fs$1.unlinkSync(getMcpAuthFilePath());
|
|
13774
|
+
} catch {
|
|
13775
|
+
}
|
|
13776
|
+
}
|
|
13746
13777
|
function asTextResponse(text) {
|
|
13747
13778
|
return { content: [{ type: "text", text }] };
|
|
13748
13779
|
}
|
|
@@ -15198,7 +15229,7 @@ function registerTools(server, tabManager, runtime2) {
|
|
|
15198
15229
|
else if (tier === 1) score = 30;
|
|
15199
15230
|
else score = 40;
|
|
15200
15231
|
return {
|
|
15201
|
-
name:
|
|
15232
|
+
name: def.name,
|
|
15202
15233
|
title: def.title,
|
|
15203
15234
|
description: def.description,
|
|
15204
15235
|
tier,
|
|
@@ -15230,10 +15261,10 @@ function registerTools(server, tabManager, runtime2) {
|
|
|
15230
15261
|
}
|
|
15231
15262
|
);
|
|
15232
15263
|
server.registerTool(
|
|
15233
|
-
"
|
|
15264
|
+
"current_tab",
|
|
15234
15265
|
{
|
|
15235
15266
|
title: "Get Active Tab",
|
|
15236
|
-
description: "Return the browser tab the human is actively looking at right now. Use this instead of
|
|
15267
|
+
description: "Return the browser tab the human is actively looking at right now. Use this instead of list_tabs when you only need the focused tab."
|
|
15237
15268
|
},
|
|
15238
15269
|
async () => {
|
|
15239
15270
|
const activeTab = getActiveTabSummary(tabManager);
|
|
@@ -15242,7 +15273,7 @@ function registerTools(server, tabManager, runtime2) {
|
|
|
15242
15273
|
}
|
|
15243
15274
|
);
|
|
15244
15275
|
server.registerTool(
|
|
15245
|
-
"
|
|
15276
|
+
"publish_transcript",
|
|
15246
15277
|
{
|
|
15247
15278
|
title: "Publish Agent Transcript",
|
|
15248
15279
|
description: "Publish or stream agent reasoning/status text into Vessel's in-browser transcript monitor. Intended for external harnesses that want to mirror live thinking into the browser UI.",
|
|
@@ -15283,7 +15314,7 @@ function registerTools(server, tabManager, runtime2) {
|
|
|
15283
15314
|
}
|
|
15284
15315
|
);
|
|
15285
15316
|
server.registerTool(
|
|
15286
|
-
"
|
|
15317
|
+
"clear_transcript",
|
|
15287
15318
|
{
|
|
15288
15319
|
title: "Clear Agent Transcript",
|
|
15289
15320
|
description: "Clear the in-browser transcript monitor state."
|
|
@@ -15334,7 +15365,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15334
15365
|
${buildScopedContext(pageContent, mode)}`;
|
|
15335
15366
|
}
|
|
15336
15367
|
server.registerTool(
|
|
15337
|
-
"
|
|
15368
|
+
"extract_content",
|
|
15338
15369
|
{
|
|
15339
15370
|
title: "Extract Page Content",
|
|
15340
15371
|
description: "Extract structured content from the current page. Modes: 'full' (default, everything), 'summary' (title+headings+stats), 'interactives_only' (clickable elements with indices), 'forms_only' (form fields only), 'text_only' (page text, no interactives), 'visible_only' (only currently visible, in-viewport, unobstructed elements plus active overlays), 'results_only' (likely primary search/result links only).",
|
|
@@ -15366,7 +15397,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15366
15397
|
}
|
|
15367
15398
|
);
|
|
15368
15399
|
server.registerTool(
|
|
15369
|
-
"
|
|
15400
|
+
"read_page",
|
|
15370
15401
|
{
|
|
15371
15402
|
title: "Read Page",
|
|
15372
15403
|
description: "Read the active tab's page content. Includes saved highlights plus any active text selection or visible unsaved highlights on the page. Supports modes: full (default — includes highlights section), summary, interactives_only, forms_only, text_only, visible_only, results_only.",
|
|
@@ -15398,7 +15429,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15398
15429
|
}
|
|
15399
15430
|
);
|
|
15400
15431
|
server.registerTool(
|
|
15401
|
-
"
|
|
15432
|
+
"list_tabs",
|
|
15402
15433
|
{
|
|
15403
15434
|
title: "List Tabs",
|
|
15404
15435
|
description: "List all open browser tabs with their IDs, titles, and URLs."
|
|
@@ -15414,7 +15445,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15414
15445
|
}
|
|
15415
15446
|
);
|
|
15416
15447
|
server.registerTool(
|
|
15417
|
-
"
|
|
15448
|
+
"navigate",
|
|
15418
15449
|
{
|
|
15419
15450
|
title: "Navigate",
|
|
15420
15451
|
description: "Navigate the active browser tab to a URL. Use postBody to submit data via POST request (e.g. form submissions).",
|
|
@@ -15455,7 +15486,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15455
15486
|
}
|
|
15456
15487
|
);
|
|
15457
15488
|
server.registerTool(
|
|
15458
|
-
"
|
|
15489
|
+
"set_ad_blocking",
|
|
15459
15490
|
{
|
|
15460
15491
|
title: "Set Ad Blocking",
|
|
15461
15492
|
description: "Enable or disable ad blocking for the active tab or a matched tab. Reload after changes unless reload is false.",
|
|
@@ -15500,7 +15531,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15500
15531
|
}
|
|
15501
15532
|
);
|
|
15502
15533
|
server.registerTool(
|
|
15503
|
-
"
|
|
15534
|
+
"extract_structured_data",
|
|
15504
15535
|
{
|
|
15505
15536
|
title: "Extract Structured Data",
|
|
15506
15537
|
description: "Return normalized structured data derived from page JSON-LD, microdata, RDFa, and high-signal meta tags. Useful for recipes, products, articles, events, FAQs, and other schema-rich pages.",
|
|
@@ -15553,7 +15584,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15553
15584
|
}
|
|
15554
15585
|
);
|
|
15555
15586
|
server.registerTool(
|
|
15556
|
-
"
|
|
15587
|
+
"go_back",
|
|
15557
15588
|
{
|
|
15558
15589
|
title: "Go Back",
|
|
15559
15590
|
description: "Go back in browser history."
|
|
@@ -15574,7 +15605,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15574
15605
|
}
|
|
15575
15606
|
);
|
|
15576
15607
|
server.registerTool(
|
|
15577
|
-
"
|
|
15608
|
+
"go_forward",
|
|
15578
15609
|
{
|
|
15579
15610
|
title: "Go Forward",
|
|
15580
15611
|
description: "Go forward in browser history."
|
|
@@ -15595,7 +15626,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15595
15626
|
}
|
|
15596
15627
|
);
|
|
15597
15628
|
server.registerTool(
|
|
15598
|
-
"
|
|
15629
|
+
"reload",
|
|
15599
15630
|
{
|
|
15600
15631
|
title: "Reload",
|
|
15601
15632
|
description: "Reload the current page."
|
|
@@ -15611,7 +15642,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15611
15642
|
}
|
|
15612
15643
|
);
|
|
15613
15644
|
server.registerTool(
|
|
15614
|
-
"
|
|
15645
|
+
"click",
|
|
15615
15646
|
{
|
|
15616
15647
|
title: "Click Element",
|
|
15617
15648
|
description: "Click an element on the page by its index number or CSS selector.",
|
|
@@ -15640,7 +15671,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15640
15671
|
}
|
|
15641
15672
|
);
|
|
15642
15673
|
server.registerTool(
|
|
15643
|
-
"
|
|
15674
|
+
"hover",
|
|
15644
15675
|
{
|
|
15645
15676
|
title: "Hover Element",
|
|
15646
15677
|
description: "Move the mouse pointer over an element to trigger hover states, tooltips, or dropdown menus.",
|
|
@@ -15669,7 +15700,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15669
15700
|
}
|
|
15670
15701
|
);
|
|
15671
15702
|
server.registerTool(
|
|
15672
|
-
"
|
|
15703
|
+
"focus",
|
|
15673
15704
|
{
|
|
15674
15705
|
title: "Focus Element",
|
|
15675
15706
|
description: "Focus an input, button, or interactive element. Useful before pressing keys or to trigger focus-dependent UI.",
|
|
@@ -15698,7 +15729,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15698
15729
|
}
|
|
15699
15730
|
);
|
|
15700
15731
|
server.registerTool(
|
|
15701
|
-
"
|
|
15732
|
+
"extract_text",
|
|
15702
15733
|
{
|
|
15703
15734
|
title: "Extract Element Text",
|
|
15704
15735
|
description: "Extract the text content of a specific element by its index number or CSS selector.",
|
|
@@ -15779,7 +15810,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15779
15810
|
}
|
|
15780
15811
|
);
|
|
15781
15812
|
server.registerTool(
|
|
15782
|
-
"
|
|
15813
|
+
"type",
|
|
15783
15814
|
{
|
|
15784
15815
|
title: "Type Text",
|
|
15785
15816
|
description: "Type text into an input field or textarea. Clears existing content first.",
|
|
@@ -15818,10 +15849,10 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15818
15849
|
}
|
|
15819
15850
|
);
|
|
15820
15851
|
server.registerTool(
|
|
15821
|
-
"
|
|
15852
|
+
"type_text",
|
|
15822
15853
|
{
|
|
15823
15854
|
title: "Type Text",
|
|
15824
|
-
description: "Alias for
|
|
15855
|
+
description: "Alias for type. Type text into an input field or textarea.",
|
|
15825
15856
|
inputSchema: {
|
|
15826
15857
|
index: zod.z.number().optional().describe("Element index from the page content listing"),
|
|
15827
15858
|
selector: zod.z.string().optional().describe("CSS selector as fallback"),
|
|
@@ -15857,7 +15888,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15857
15888
|
}
|
|
15858
15889
|
);
|
|
15859
15890
|
server.registerTool(
|
|
15860
|
-
"
|
|
15891
|
+
"select_option",
|
|
15861
15892
|
{
|
|
15862
15893
|
title: "Select Option",
|
|
15863
15894
|
description: "Select an option in a dropdown by label or value.",
|
|
@@ -15881,7 +15912,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15881
15912
|
}
|
|
15882
15913
|
);
|
|
15883
15914
|
server.registerTool(
|
|
15884
|
-
"
|
|
15915
|
+
"submit_form",
|
|
15885
15916
|
{
|
|
15886
15917
|
title: "Submit Form",
|
|
15887
15918
|
description: "Submit a form using a field index, submit button index, form selector, or button selector.",
|
|
@@ -15913,7 +15944,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15913
15944
|
}
|
|
15914
15945
|
);
|
|
15915
15946
|
server.registerTool(
|
|
15916
|
-
"
|
|
15947
|
+
"press_key",
|
|
15917
15948
|
{
|
|
15918
15949
|
title: "Press Key",
|
|
15919
15950
|
description: "Press a keyboard key, optionally after focusing an element.",
|
|
@@ -15948,7 +15979,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15948
15979
|
}
|
|
15949
15980
|
);
|
|
15950
15981
|
server.registerTool(
|
|
15951
|
-
"
|
|
15982
|
+
"scroll",
|
|
15952
15983
|
{
|
|
15953
15984
|
title: "Scroll Page",
|
|
15954
15985
|
description: "Scroll the page up or down.",
|
|
@@ -15977,7 +16008,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15977
16008
|
}
|
|
15978
16009
|
);
|
|
15979
16010
|
server.registerTool(
|
|
15980
|
-
"
|
|
16011
|
+
"dismiss_popup",
|
|
15981
16012
|
{
|
|
15982
16013
|
title: "Dismiss Popup",
|
|
15983
16014
|
description: "Dismiss a modal, popup, newsletter gate, cookie banner, or blocking overlay using common close and decline actions."
|
|
@@ -15995,7 +16026,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
15995
16026
|
}
|
|
15996
16027
|
);
|
|
15997
16028
|
server.registerTool(
|
|
15998
|
-
"
|
|
16029
|
+
"clear_overlays",
|
|
15999
16030
|
{
|
|
16000
16031
|
title: "Clear Overlays",
|
|
16001
16032
|
description: "Work through blocking overlays and modals until the page is unblocked, using overlay-specific heuristics for consent banners and radio-selection dialogs.",
|
|
@@ -16021,7 +16052,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16021
16052
|
}
|
|
16022
16053
|
);
|
|
16023
16054
|
server.registerTool(
|
|
16024
|
-
"
|
|
16055
|
+
"wait_for",
|
|
16025
16056
|
{
|
|
16026
16057
|
title: "Wait For",
|
|
16027
16058
|
description: "Wait for text or a selector to appear on the current page.",
|
|
@@ -16044,7 +16075,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16044
16075
|
}
|
|
16045
16076
|
);
|
|
16046
16077
|
server.registerTool(
|
|
16047
|
-
"
|
|
16078
|
+
"create_tab",
|
|
16048
16079
|
{
|
|
16049
16080
|
title: "Create Tab",
|
|
16050
16081
|
description: "Open a new browser tab, optionally navigating to a URL.",
|
|
@@ -16062,7 +16093,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16062
16093
|
})
|
|
16063
16094
|
);
|
|
16064
16095
|
server.registerTool(
|
|
16065
|
-
"
|
|
16096
|
+
"switch_tab",
|
|
16066
16097
|
{
|
|
16067
16098
|
title: "Switch Tab",
|
|
16068
16099
|
description: "Switch to a different browser tab by ID or title/URL match.",
|
|
@@ -16087,7 +16118,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16087
16118
|
)
|
|
16088
16119
|
);
|
|
16089
16120
|
server.registerTool(
|
|
16090
|
-
"
|
|
16121
|
+
"close_tab",
|
|
16091
16122
|
{
|
|
16092
16123
|
title: "Close Tab",
|
|
16093
16124
|
description: "Close a browser tab by its ID.",
|
|
@@ -16101,7 +16132,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16101
16132
|
})
|
|
16102
16133
|
);
|
|
16103
16134
|
server.registerTool(
|
|
16104
|
-
"
|
|
16135
|
+
"checkpoint_create",
|
|
16105
16136
|
{
|
|
16106
16137
|
title: "Create Checkpoint",
|
|
16107
16138
|
description: "Capture the current session as a named checkpoint.",
|
|
@@ -16122,7 +16153,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16122
16153
|
)
|
|
16123
16154
|
);
|
|
16124
16155
|
server.registerTool(
|
|
16125
|
-
"
|
|
16156
|
+
"checkpoint_restore",
|
|
16126
16157
|
{
|
|
16127
16158
|
title: "Restore Checkpoint",
|
|
16128
16159
|
description: "Restore a saved checkpoint by ID or exact name.",
|
|
@@ -16148,7 +16179,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16148
16179
|
)
|
|
16149
16180
|
);
|
|
16150
16181
|
server.registerTool(
|
|
16151
|
-
"
|
|
16182
|
+
"save_session",
|
|
16152
16183
|
{
|
|
16153
16184
|
title: "Save Session",
|
|
16154
16185
|
description: "Persist the current cookies, localStorage, and tab layout under a reusable session name.",
|
|
@@ -16165,7 +16196,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16165
16196
|
})
|
|
16166
16197
|
);
|
|
16167
16198
|
server.registerTool(
|
|
16168
|
-
"
|
|
16199
|
+
"load_session",
|
|
16169
16200
|
{
|
|
16170
16201
|
title: "Load Session",
|
|
16171
16202
|
description: "Load a previously saved named session, restoring cookies, localStorage, and saved tabs.",
|
|
@@ -16182,7 +16213,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16182
16213
|
})
|
|
16183
16214
|
);
|
|
16184
16215
|
server.registerTool(
|
|
16185
|
-
"
|
|
16216
|
+
"list_sessions",
|
|
16186
16217
|
{
|
|
16187
16218
|
title: "List Sessions",
|
|
16188
16219
|
description: "List previously saved named browser sessions with cookie and storage counts."
|
|
@@ -16196,7 +16227,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16196
16227
|
})
|
|
16197
16228
|
);
|
|
16198
16229
|
server.registerTool(
|
|
16199
|
-
"
|
|
16230
|
+
"delete_session",
|
|
16200
16231
|
{
|
|
16201
16232
|
title: "Delete Session",
|
|
16202
16233
|
description: "Delete a previously saved named browser session.",
|
|
@@ -16213,7 +16244,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
16213
16244
|
)
|
|
16214
16245
|
);
|
|
16215
16246
|
server.registerTool(
|
|
16216
|
-
"
|
|
16247
|
+
"screenshot",
|
|
16217
16248
|
{
|
|
16218
16249
|
title: "Screenshot",
|
|
16219
16250
|
description: "Capture a screenshot of the current page. Returns a base64-encoded PNG image."
|
|
@@ -16265,7 +16296,7 @@ To analyze visually, call vision_analyze with image_url="${screenshotPath}"`
|
|
|
16265
16296
|
}
|
|
16266
16297
|
);
|
|
16267
16298
|
server.registerTool(
|
|
16268
|
-
"
|
|
16299
|
+
"highlight",
|
|
16269
16300
|
{
|
|
16270
16301
|
title: "Highlight Element",
|
|
16271
16302
|
description: "Visually highlight an element or text on the page for the user. Use to draw attention to specific parts of the page. Highlights persist until cleared. Set persist=true to save the highlight so it re-appears when the user revisits this page.",
|
|
@@ -16332,7 +16363,7 @@ To analyze visually, call vision_analyze with image_url="${screenshotPath}"`
|
|
|
16332
16363
|
}
|
|
16333
16364
|
);
|
|
16334
16365
|
server.registerTool(
|
|
16335
|
-
"
|
|
16366
|
+
"clear_highlights",
|
|
16336
16367
|
{
|
|
16337
16368
|
title: "Clear Highlights",
|
|
16338
16369
|
description: "Remove all visual highlights from the current page, including any saved persistent highlights for this URL."
|
|
@@ -16355,7 +16386,7 @@ To analyze visually, call vision_analyze with image_url="${screenshotPath}"`
|
|
|
16355
16386
|
}
|
|
16356
16387
|
);
|
|
16357
16388
|
server.registerTool(
|
|
16358
|
-
"
|
|
16389
|
+
"list_highlights",
|
|
16359
16390
|
{
|
|
16360
16391
|
title: "List Highlights",
|
|
16361
16392
|
description: "List highlights related to the current browsing session. Includes saved persistent highlights plus the active tab's live text selection and any visible unsaved highlight marks. IMPORTANT: When the user says they highlighted or selected text, call this tool before falling back to screenshots or vision.",
|
|
@@ -16447,10 +16478,10 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16447
16478
|
}
|
|
16448
16479
|
);
|
|
16449
16480
|
server.registerTool(
|
|
16450
|
-
"
|
|
16481
|
+
"remove_highlight",
|
|
16451
16482
|
{
|
|
16452
16483
|
title: "Remove Persistent Highlight",
|
|
16453
|
-
description: "Remove a persistent highlight by ID and clear it from any open tab. Use
|
|
16484
|
+
description: "Remove a persistent highlight by ID and clear it from any open tab. Use list_highlights to find IDs.",
|
|
16454
16485
|
inputSchema: {
|
|
16455
16486
|
id: zod.z.string().describe("ID of the highlight to remove")
|
|
16456
16487
|
}
|
|
@@ -16486,7 +16517,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16486
16517
|
}
|
|
16487
16518
|
);
|
|
16488
16519
|
server.registerTool(
|
|
16489
|
-
"
|
|
16520
|
+
"create_folder",
|
|
16490
16521
|
{
|
|
16491
16522
|
title: "Create Bookmark Folder",
|
|
16492
16523
|
description: "Create a named folder for organizing bookmarks. If a folder with the same name already exists, return it instead of duplicating it.",
|
|
@@ -16517,7 +16548,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16517
16548
|
}
|
|
16518
16549
|
);
|
|
16519
16550
|
server.registerTool(
|
|
16520
|
-
"
|
|
16551
|
+
"bookmark_save",
|
|
16521
16552
|
{
|
|
16522
16553
|
title: "Save Bookmark",
|
|
16523
16554
|
description: "Save the current page, a specific URL, or a link target from the current page into a bookmark folder. You can provide folder_id or folder_name; missing folder names can be created automatically.",
|
|
@@ -16627,7 +16658,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16627
16658
|
}
|
|
16628
16659
|
);
|
|
16629
16660
|
server.registerTool(
|
|
16630
|
-
"
|
|
16661
|
+
"bookmark_list",
|
|
16631
16662
|
{
|
|
16632
16663
|
title: "List Bookmarks",
|
|
16633
16664
|
description: "List all bookmark folders and their contents. Optionally filter by folder.",
|
|
@@ -16677,7 +16708,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16677
16708
|
}
|
|
16678
16709
|
);
|
|
16679
16710
|
server.registerTool(
|
|
16680
|
-
"
|
|
16711
|
+
"bookmark_organize",
|
|
16681
16712
|
{
|
|
16682
16713
|
title: "Organize Bookmark",
|
|
16683
16714
|
description: "Organize a bookmark by intent: save or move a bookmark into a folder, creating the folder if needed. Works with bookmark_id, url, a link target from the current page, or the current page itself.",
|
|
@@ -16760,7 +16791,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16760
16791
|
}
|
|
16761
16792
|
);
|
|
16762
16793
|
server.registerTool(
|
|
16763
|
-
"
|
|
16794
|
+
"bookmark_search",
|
|
16764
16795
|
{
|
|
16765
16796
|
title: "Search Bookmarks",
|
|
16766
16797
|
description: "Search bookmarks by title, URL, note, folder name, or folder summary.",
|
|
@@ -16791,7 +16822,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16791
16822
|
}
|
|
16792
16823
|
);
|
|
16793
16824
|
server.registerTool(
|
|
16794
|
-
"
|
|
16825
|
+
"bookmark_remove",
|
|
16795
16826
|
{
|
|
16796
16827
|
title: "Remove Bookmark",
|
|
16797
16828
|
description: "Remove a specific bookmark by its ID.",
|
|
@@ -16813,7 +16844,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16813
16844
|
}
|
|
16814
16845
|
);
|
|
16815
16846
|
server.registerTool(
|
|
16816
|
-
"
|
|
16847
|
+
"bookmark_archive",
|
|
16817
16848
|
{
|
|
16818
16849
|
title: "Archive Bookmark",
|
|
16819
16850
|
description: 'Archive the current page, a URL, a link target from the current page, or an existing bookmark into the default "Archive" folder.',
|
|
@@ -16893,7 +16924,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16893
16924
|
}
|
|
16894
16925
|
);
|
|
16895
16926
|
server.registerTool(
|
|
16896
|
-
"
|
|
16927
|
+
"bookmark_open",
|
|
16897
16928
|
{
|
|
16898
16929
|
title: "Open Bookmark",
|
|
16899
16930
|
description: "Open a saved bookmark by bookmark ID. Optionally open it in a new tab.",
|
|
@@ -16937,7 +16968,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16937
16968
|
}
|
|
16938
16969
|
);
|
|
16939
16970
|
server.registerTool(
|
|
16940
|
-
"
|
|
16971
|
+
"folder_remove",
|
|
16941
16972
|
{
|
|
16942
16973
|
title: "Remove Bookmark Folder",
|
|
16943
16974
|
description: "Remove a folder. Bookmarks in it are moved to Unsorted.",
|
|
@@ -16961,7 +16992,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16961
16992
|
}
|
|
16962
16993
|
);
|
|
16963
16994
|
server.registerTool(
|
|
16964
|
-
"
|
|
16995
|
+
"folder_rename",
|
|
16965
16996
|
{
|
|
16966
16997
|
title: "Rename Bookmark Folder",
|
|
16967
16998
|
description: "Rename an existing bookmark folder.",
|
|
@@ -16995,7 +17026,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
16995
17026
|
}
|
|
16996
17027
|
);
|
|
16997
17028
|
server.registerTool(
|
|
16998
|
-
"
|
|
17029
|
+
"memory_note_create",
|
|
16999
17030
|
{
|
|
17000
17031
|
title: "Create Memory Note",
|
|
17001
17032
|
description: "Write a markdown note into the configured Obsidian vault for research notes, breadcrumbs, or synthesis.",
|
|
@@ -17022,7 +17053,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
17022
17053
|
}
|
|
17023
17054
|
);
|
|
17024
17055
|
server.registerTool(
|
|
17025
|
-
"
|
|
17056
|
+
"memory_append",
|
|
17026
17057
|
{
|
|
17027
17058
|
title: "Append Memory Note",
|
|
17028
17059
|
description: "Append markdown content to an existing note in the configured Obsidian vault.",
|
|
@@ -17050,7 +17081,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
17050
17081
|
}
|
|
17051
17082
|
);
|
|
17052
17083
|
server.registerTool(
|
|
17053
|
-
"
|
|
17084
|
+
"memory_list",
|
|
17054
17085
|
{
|
|
17055
17086
|
title: "List Memory Notes",
|
|
17056
17087
|
description: "List recent markdown notes in the configured Obsidian vault.",
|
|
@@ -17078,7 +17109,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
17078
17109
|
}
|
|
17079
17110
|
);
|
|
17080
17111
|
server.registerTool(
|
|
17081
|
-
"
|
|
17112
|
+
"memory_search",
|
|
17082
17113
|
{
|
|
17083
17114
|
title: "Search Memory Notes",
|
|
17084
17115
|
description: "Search markdown notes in the configured Obsidian vault by title, path, body, and optional tags.",
|
|
@@ -17108,7 +17139,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
17108
17139
|
}
|
|
17109
17140
|
);
|
|
17110
17141
|
server.registerTool(
|
|
17111
|
-
"
|
|
17142
|
+
"memory_page_capture",
|
|
17112
17143
|
{
|
|
17113
17144
|
title: "Capture Page To Memory",
|
|
17114
17145
|
description: "Capture the current page into the configured Obsidian vault as a markdown note with URL, excerpt, and content snapshot.",
|
|
@@ -17144,7 +17175,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
17144
17175
|
}
|
|
17145
17176
|
);
|
|
17146
17177
|
server.registerTool(
|
|
17147
|
-
"
|
|
17178
|
+
"memory_link_bookmark",
|
|
17148
17179
|
{
|
|
17149
17180
|
title: "Link Bookmark To Memory",
|
|
17150
17181
|
description: "Create a note for a bookmark or append bookmark details into an existing memory note.",
|
|
@@ -17184,7 +17215,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
17184
17215
|
}
|
|
17185
17216
|
);
|
|
17186
17217
|
server.registerTool(
|
|
17187
|
-
"
|
|
17218
|
+
"flow_start",
|
|
17188
17219
|
{
|
|
17189
17220
|
title: "Start Workflow",
|
|
17190
17221
|
description: "Begin tracking a multi-step web workflow. Vessel will show progress after every action so you always know where you are in the flow.",
|
|
@@ -17212,7 +17243,7 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
17212
17243
|
}
|
|
17213
17244
|
);
|
|
17214
17245
|
server.registerTool(
|
|
17215
|
-
"
|
|
17246
|
+
"flow_advance",
|
|
17216
17247
|
{
|
|
17217
17248
|
title: "Advance Workflow Step",
|
|
17218
17249
|
description: "Mark the current workflow step as done and move to the next one. Call this after completing each step.",
|
|
@@ -17228,7 +17259,7 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
17228
17259
|
}
|
|
17229
17260
|
);
|
|
17230
17261
|
server.registerTool(
|
|
17231
|
-
"
|
|
17262
|
+
"flow_status",
|
|
17232
17263
|
{
|
|
17233
17264
|
title: "Workflow Status",
|
|
17234
17265
|
description: "Check the current workflow progress."
|
|
@@ -17240,7 +17271,7 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
17240
17271
|
}
|
|
17241
17272
|
);
|
|
17242
17273
|
server.registerTool(
|
|
17243
|
-
"
|
|
17274
|
+
"flow_end",
|
|
17244
17275
|
{
|
|
17245
17276
|
title: "End Workflow",
|
|
17246
17277
|
description: "Clear the active workflow tracker."
|
|
@@ -17251,7 +17282,7 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
17251
17282
|
}
|
|
17252
17283
|
);
|
|
17253
17284
|
server.registerTool(
|
|
17254
|
-
"
|
|
17285
|
+
"suggest",
|
|
17255
17286
|
{
|
|
17256
17287
|
title: "What Should I Do?",
|
|
17257
17288
|
description: "Analyze the current page and return the most relevant tools and suggested next actions. Call this when you're unsure what to do next — it reads the page context and tells you the optimal approach."
|
|
@@ -17260,7 +17291,7 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
17260
17291
|
const tab = tabManager.getActiveTab();
|
|
17261
17292
|
if (!tab)
|
|
17262
17293
|
return asTextResponse(
|
|
17263
|
-
"No active tab. Use
|
|
17294
|
+
"No active tab. Use navigate to open a page."
|
|
17264
17295
|
);
|
|
17265
17296
|
const wc = tab.view.webContents;
|
|
17266
17297
|
let page;
|
|
@@ -17268,7 +17299,7 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
17268
17299
|
page = await extractContent(wc);
|
|
17269
17300
|
} catch {
|
|
17270
17301
|
return asTextResponse(
|
|
17271
|
-
"Could not read page. Try
|
|
17302
|
+
"Could not read page. Try navigate to a working URL."
|
|
17272
17303
|
);
|
|
17273
17304
|
}
|
|
17274
17305
|
const suggestions = [];
|
|
@@ -17298,50 +17329,50 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
17298
17329
|
const hasOverlays = page.overlays.some((o) => o.blocksInteraction);
|
|
17299
17330
|
if (hasOverlays) {
|
|
17300
17331
|
suggestions.push("⚠ BLOCKING OVERLAY detected — dismiss it first:");
|
|
17301
|
-
suggestions.push(" →
|
|
17302
|
-
suggestions.push(" → or
|
|
17332
|
+
suggestions.push(" → clear_overlays for stacked modals");
|
|
17333
|
+
suggestions.push(" → or dismiss_popup for a single popup");
|
|
17303
17334
|
suggestions.push("");
|
|
17304
17335
|
}
|
|
17305
17336
|
if (hasPasswordField) {
|
|
17306
17337
|
suggestions.push("🔑 LOGIN PAGE detected:");
|
|
17307
17338
|
suggestions.push(
|
|
17308
|
-
" →
|
|
17339
|
+
" → login(username, password) — handles the full flow"
|
|
17309
17340
|
);
|
|
17310
17341
|
suggestions.push(
|
|
17311
|
-
" → Or
|
|
17342
|
+
" → Or fill_form + submit_form for manual control"
|
|
17312
17343
|
);
|
|
17313
17344
|
} else if (hasSearchInput && linkCount < 10) {
|
|
17314
17345
|
suggestions.push("🔍 SEARCH PAGE detected:");
|
|
17315
17346
|
suggestions.push(
|
|
17316
|
-
" →
|
|
17347
|
+
" → search(query) — finds the box, types, submits"
|
|
17317
17348
|
);
|
|
17318
17349
|
} else if (hasSearchInput && linkCount >= 10) {
|
|
17319
17350
|
suggestions.push("📋 SEARCH RESULTS detected:");
|
|
17320
|
-
suggestions.push(" →
|
|
17351
|
+
suggestions.push(" → click on a result link");
|
|
17321
17352
|
if (hasPagination) {
|
|
17322
|
-
suggestions.push(" →
|
|
17353
|
+
suggestions.push(" → paginate('next') for more results");
|
|
17323
17354
|
}
|
|
17324
17355
|
} else if (formCount > 0) {
|
|
17325
17356
|
suggestions.push(`📝 FORM detected (${totalFields} fields):`);
|
|
17326
17357
|
suggestions.push(
|
|
17327
|
-
" →
|
|
17358
|
+
" → fill_form(fields) — fill all fields at once"
|
|
17328
17359
|
);
|
|
17329
|
-
suggestions.push(" → Or
|
|
17360
|
+
suggestions.push(" → Or type for individual fields");
|
|
17330
17361
|
} else if (hasPagination) {
|
|
17331
17362
|
suggestions.push("📄 PAGINATED CONTENT:");
|
|
17332
|
-
suggestions.push(" →
|
|
17333
|
-
suggestions.push(" →
|
|
17363
|
+
suggestions.push(" → extract_content to read this page");
|
|
17364
|
+
suggestions.push(" → paginate('next') for the next page");
|
|
17334
17365
|
} else if (page.content.length > 3e3 && page.interactiveElements.length < 10) {
|
|
17335
17366
|
suggestions.push("📖 ARTICLE/CONTENT page:");
|
|
17336
|
-
suggestions.push(" →
|
|
17337
|
-
suggestions.push(" →
|
|
17367
|
+
suggestions.push(" → extract_content for readable text");
|
|
17368
|
+
suggestions.push(" → scroll to see more");
|
|
17338
17369
|
} else {
|
|
17339
17370
|
suggestions.push("🌐 GENERAL PAGE:");
|
|
17340
17371
|
suggestions.push(
|
|
17341
|
-
" →
|
|
17372
|
+
" → extract_content to understand the page structure"
|
|
17342
17373
|
);
|
|
17343
|
-
suggestions.push(" →
|
|
17344
|
-
suggestions.push(" →
|
|
17374
|
+
suggestions.push(" → click on any element by index");
|
|
17375
|
+
suggestions.push(" → navigate to go somewhere new");
|
|
17345
17376
|
}
|
|
17346
17377
|
suggestions.push("");
|
|
17347
17378
|
suggestions.push(
|
|
@@ -17351,7 +17382,7 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
17351
17382
|
}
|
|
17352
17383
|
);
|
|
17353
17384
|
server.registerTool(
|
|
17354
|
-
"
|
|
17385
|
+
"fill_form",
|
|
17355
17386
|
{
|
|
17356
17387
|
title: "Fill Form",
|
|
17357
17388
|
description: "Fill multiple form fields at once. Provide a map of field identifiers to values. Fields are matched by index, name, label, or placeholder. Much faster than calling type for each field individually.",
|
|
@@ -17402,7 +17433,7 @@ ${results.join("\n")}`;
|
|
|
17402
17433
|
}
|
|
17403
17434
|
);
|
|
17404
17435
|
server.registerTool(
|
|
17405
|
-
"
|
|
17436
|
+
"login",
|
|
17406
17437
|
{
|
|
17407
17438
|
title: "Login",
|
|
17408
17439
|
description: "Compound action: navigate to a login page, fill credentials, and submit. Handles the full login flow in one call.",
|
|
@@ -17493,7 +17524,7 @@ ${steps.join("\n")}`;
|
|
|
17493
17524
|
}
|
|
17494
17525
|
);
|
|
17495
17526
|
server.registerTool(
|
|
17496
|
-
"
|
|
17527
|
+
"search",
|
|
17497
17528
|
{
|
|
17498
17529
|
title: "Search",
|
|
17499
17530
|
description: "Compound action: find a search box on the current page, type a query, and submit. Returns the resulting page state.",
|
|
@@ -17576,7 +17607,7 @@ ${steps.join("\n")}`;
|
|
|
17576
17607
|
}
|
|
17577
17608
|
);
|
|
17578
17609
|
server.registerTool(
|
|
17579
|
-
"
|
|
17610
|
+
"paginate",
|
|
17580
17611
|
{
|
|
17581
17612
|
title: "Paginate",
|
|
17582
17613
|
description: "Navigate to the next or previous page of results. Auto-detects pagination controls.",
|
|
@@ -17632,7 +17663,7 @@ ${steps.join("\n")}`;
|
|
|
17632
17663
|
}
|
|
17633
17664
|
);
|
|
17634
17665
|
server.registerTool(
|
|
17635
|
-
"
|
|
17666
|
+
"accept_cookies",
|
|
17636
17667
|
{
|
|
17637
17668
|
title: "Accept Cookies",
|
|
17638
17669
|
description: "Dismiss cookie consent banners (OneTrust, CookieBot, GDPR popups, etc.).",
|
|
@@ -17644,7 +17675,7 @@ ${steps.join("\n")}`;
|
|
|
17644
17675
|
return withAction(
|
|
17645
17676
|
runtime2,
|
|
17646
17677
|
tabManager,
|
|
17647
|
-
"
|
|
17678
|
+
"accept_cookies",
|
|
17648
17679
|
{},
|
|
17649
17680
|
async () => {
|
|
17650
17681
|
const wc = tab.view.webContents;
|
|
@@ -17681,13 +17712,13 @@ ${steps.join("\n")}`;
|
|
|
17681
17712
|
return null;
|
|
17682
17713
|
})()
|
|
17683
17714
|
`);
|
|
17684
|
-
return dismissed || "No cookie consent banner detected. Try
|
|
17715
|
+
return dismissed || "No cookie consent banner detected. Try dismiss_popup for other overlays.";
|
|
17685
17716
|
}
|
|
17686
17717
|
);
|
|
17687
17718
|
}
|
|
17688
17719
|
);
|
|
17689
17720
|
server.registerTool(
|
|
17690
|
-
"
|
|
17721
|
+
"extract_table",
|
|
17691
17722
|
{
|
|
17692
17723
|
title: "Extract Table",
|
|
17693
17724
|
description: "Extract a table from the page as structured JSON rows with headers.",
|
|
@@ -17702,7 +17733,7 @@ ${steps.join("\n")}`;
|
|
|
17702
17733
|
return withAction(
|
|
17703
17734
|
runtime2,
|
|
17704
17735
|
tabManager,
|
|
17705
|
-
"
|
|
17736
|
+
"extract_table",
|
|
17706
17737
|
{ index, selector: rawSelector },
|
|
17707
17738
|
async () => {
|
|
17708
17739
|
const wc = tab.view.webContents;
|
|
@@ -17741,7 +17772,7 @@ ${JSON.stringify(tableJson, null, 2)}`;
|
|
|
17741
17772
|
}
|
|
17742
17773
|
);
|
|
17743
17774
|
server.registerTool(
|
|
17744
|
-
"
|
|
17775
|
+
"scroll_to_element",
|
|
17745
17776
|
{
|
|
17746
17777
|
title: "Scroll To Element",
|
|
17747
17778
|
description: "Scroll a specific element into view by index or selector.",
|
|
@@ -17757,7 +17788,7 @@ ${JSON.stringify(tableJson, null, 2)}`;
|
|
|
17757
17788
|
return withAction(
|
|
17758
17789
|
runtime2,
|
|
17759
17790
|
tabManager,
|
|
17760
|
-
"
|
|
17791
|
+
"scroll_to_element",
|
|
17761
17792
|
{ index, selector: rawSelector, position },
|
|
17762
17793
|
async () => {
|
|
17763
17794
|
const wc = tab.view.webContents;
|
|
@@ -17801,7 +17832,7 @@ ${JSON.stringify(tableJson, null, 2)}`;
|
|
|
17801
17832
|
}
|
|
17802
17833
|
);
|
|
17803
17834
|
server.registerTool(
|
|
17804
|
-
"
|
|
17835
|
+
"wait_for_navigation",
|
|
17805
17836
|
{
|
|
17806
17837
|
title: "Wait For Navigation",
|
|
17807
17838
|
description: "Wait for the current page to finish loading after a click or form submission.",
|
|
@@ -17815,7 +17846,7 @@ ${JSON.stringify(tableJson, null, 2)}`;
|
|
|
17815
17846
|
return withAction(
|
|
17816
17847
|
runtime2,
|
|
17817
17848
|
tabManager,
|
|
17818
|
-
"
|
|
17849
|
+
"wait_for_navigation",
|
|
17819
17850
|
{ timeoutMs },
|
|
17820
17851
|
async () => {
|
|
17821
17852
|
const wc = tab.view.webContents;
|
|
@@ -17857,7 +17888,7 @@ ${JSON.stringify(tableJson, null, 2)}`;
|
|
|
17857
17888
|
}
|
|
17858
17889
|
);
|
|
17859
17890
|
server.registerTool(
|
|
17860
|
-
"
|
|
17891
|
+
"vault_status",
|
|
17861
17892
|
{
|
|
17862
17893
|
title: "Check Vault Credentials",
|
|
17863
17894
|
description: "Check whether stored credentials exist for a domain. Returns credential labels and usernames but NEVER password values. Use this before vault_login to verify credentials are available.",
|
|
@@ -17899,12 +17930,12 @@ ${JSON.stringify(tableJson, null, 2)}`;
|
|
|
17899
17930
|
`Found ${matches.length} credential(s) for ${targetDomain}:
|
|
17900
17931
|
${summary}
|
|
17901
17932
|
|
|
17902
|
-
Use
|
|
17933
|
+
Use vault_login to fill the login form. Credentials are filled directly — you will NOT see the password values.`
|
|
17903
17934
|
);
|
|
17904
17935
|
}
|
|
17905
17936
|
);
|
|
17906
17937
|
server.registerTool(
|
|
17907
|
-
"
|
|
17938
|
+
"vault_login",
|
|
17908
17939
|
{
|
|
17909
17940
|
title: "Fill Login with Vault Credentials",
|
|
17910
17941
|
description: "Fill a login form on the current page using stored credentials from the Agent Credential Vault. The credential values are filled directly into the page — they are NEVER returned in this response. The user will see a consent dialog before credentials are used.",
|
|
@@ -18010,7 +18041,7 @@ Use vessel_vault_login to fill the login form. Credentials are filled directly
|
|
|
18010
18041
|
}
|
|
18011
18042
|
);
|
|
18012
18043
|
server.registerTool(
|
|
18013
|
-
"
|
|
18044
|
+
"vault_totp",
|
|
18014
18045
|
{
|
|
18015
18046
|
title: "Fill TOTP Code from Vault",
|
|
18016
18047
|
description: "Generate a TOTP 2FA code from a stored secret and fill it into a code input field. The TOTP secret and generated code are NEVER returned — only filled directly into the page.",
|
|
@@ -18095,7 +18126,7 @@ Use vessel_vault_login to fill the login form. Credentials are filled directly
|
|
|
18095
18126
|
}
|
|
18096
18127
|
);
|
|
18097
18128
|
server.registerTool(
|
|
18098
|
-
"
|
|
18129
|
+
"metrics",
|
|
18099
18130
|
{
|
|
18100
18131
|
title: "Session Metrics",
|
|
18101
18132
|
description: "Show performance metrics: total tool calls, average duration, per-tool breakdown.",
|
|
@@ -18339,6 +18370,7 @@ function startMcpServer(tabManager, runtime2, port) {
|
|
|
18339
18370
|
server.once("error", (error) => {
|
|
18340
18371
|
const message = error.code === "EADDRINUSE" ? `Port ${port} is already in use. MCP server not started.` : error.message;
|
|
18341
18372
|
console.error("[Vessel MCP] Server error:", error);
|
|
18373
|
+
clearMcpAuthFile();
|
|
18342
18374
|
setMcpHealth({
|
|
18343
18375
|
configuredPort: port,
|
|
18344
18376
|
activePort: null,
|
|
@@ -18371,6 +18403,9 @@ function startMcpServer(tabManager, runtime2, port) {
|
|
|
18371
18403
|
message: `MCP server listening on ${endpoint}.`
|
|
18372
18404
|
});
|
|
18373
18405
|
console.log(`[Vessel MCP] Server listening on ${endpoint} (auth enabled)`);
|
|
18406
|
+
if (mcpAuthToken) {
|
|
18407
|
+
writeMcpAuthFile(endpoint, mcpAuthToken);
|
|
18408
|
+
}
|
|
18374
18409
|
finish({
|
|
18375
18410
|
ok: true,
|
|
18376
18411
|
configuredPort: port,
|
|
@@ -18396,6 +18431,7 @@ function stopMcpServer() {
|
|
|
18396
18431
|
const server = httpServer;
|
|
18397
18432
|
httpServer = null;
|
|
18398
18433
|
mcpAuthToken = null;
|
|
18434
|
+
clearMcpAuthFile();
|
|
18399
18435
|
server.close(() => {
|
|
18400
18436
|
setMcpHealth({
|
|
18401
18437
|
activePort: null,
|
|
@@ -18787,11 +18823,77 @@ function assertNumber(value, name) {
|
|
|
18787
18823
|
const VALID_APPROVAL_MODES = /* @__PURE__ */ new Set(["auto", "confirm-dangerous", "manual"]);
|
|
18788
18824
|
function registerIpcHandlers(windowState, runtime2) {
|
|
18789
18825
|
const { tabManager, chromeView, sidebarView, devtoolsPanelView, mainWindow } = windowState;
|
|
18826
|
+
const premiumApiOrigin = process.env.VESSEL_PREMIUM_API ? new URL(process.env.VESSEL_PREMIUM_API).origin : "https://vesselpremium.quantaintellect.com";
|
|
18790
18827
|
const sendToRendererViews = (channel, ...args) => {
|
|
18791
18828
|
chromeView.webContents.send(channel, ...args);
|
|
18792
18829
|
sidebarView.webContents.send(channel, ...args);
|
|
18793
18830
|
devtoolsPanelView.webContents.send(channel, ...args);
|
|
18794
18831
|
};
|
|
18832
|
+
const watchPremiumCheckoutTab = (tabId) => {
|
|
18833
|
+
const tab = tabManager.getTab(tabId);
|
|
18834
|
+
const wc = tab?.view.webContents;
|
|
18835
|
+
if (!wc) return;
|
|
18836
|
+
let completed = false;
|
|
18837
|
+
const cleanup = () => {
|
|
18838
|
+
wc.removeListener("did-navigate", onNavigate);
|
|
18839
|
+
wc.removeListener("did-navigate-in-page", onNavigateInPage);
|
|
18840
|
+
wc.removeListener("destroyed", cleanup);
|
|
18841
|
+
};
|
|
18842
|
+
const handleUrl = async (rawUrl) => {
|
|
18843
|
+
if (completed) return;
|
|
18844
|
+
let parsed;
|
|
18845
|
+
try {
|
|
18846
|
+
parsed = new URL(rawUrl);
|
|
18847
|
+
} catch {
|
|
18848
|
+
return;
|
|
18849
|
+
}
|
|
18850
|
+
if (parsed.origin !== premiumApiOrigin) return;
|
|
18851
|
+
if (parsed.pathname === "/canceled") {
|
|
18852
|
+
completed = true;
|
|
18853
|
+
trackPremiumFunnel("checkout_canceled");
|
|
18854
|
+
cleanup();
|
|
18855
|
+
return;
|
|
18856
|
+
}
|
|
18857
|
+
if (parsed.pathname !== "/success") return;
|
|
18858
|
+
completed = true;
|
|
18859
|
+
trackPremiumFunnel("checkout_success_seen");
|
|
18860
|
+
const sessionId = parsed.searchParams.get("session_id")?.trim();
|
|
18861
|
+
if (!sessionId) {
|
|
18862
|
+
trackPremiumFunnel("auto_activation_failed", {
|
|
18863
|
+
reason: "missing_session_id"
|
|
18864
|
+
});
|
|
18865
|
+
cleanup();
|
|
18866
|
+
return;
|
|
18867
|
+
}
|
|
18868
|
+
trackPremiumFunnel("auto_activation_attempted");
|
|
18869
|
+
const state2 = await verifySubscription(sessionId);
|
|
18870
|
+
if (isPremiumActiveState(state2)) {
|
|
18871
|
+
sendToRendererViews(Channels.PREMIUM_UPDATE, state2);
|
|
18872
|
+
trackPremiumFunnel("auto_activation_succeeded", {
|
|
18873
|
+
status: state2.status
|
|
18874
|
+
});
|
|
18875
|
+
} else {
|
|
18876
|
+
trackPremiumFunnel("auto_activation_failed", {
|
|
18877
|
+
status: state2.status
|
|
18878
|
+
});
|
|
18879
|
+
}
|
|
18880
|
+
cleanup();
|
|
18881
|
+
};
|
|
18882
|
+
const onNavigate = (_event, url) => {
|
|
18883
|
+
void handleUrl(url);
|
|
18884
|
+
};
|
|
18885
|
+
const onNavigateInPage = (_event, url, isMainFrame) => {
|
|
18886
|
+
if (!isMainFrame) return;
|
|
18887
|
+
void handleUrl(url);
|
|
18888
|
+
};
|
|
18889
|
+
wc.on("did-navigate", onNavigate);
|
|
18890
|
+
wc.on("did-navigate-in-page", onNavigateInPage);
|
|
18891
|
+
wc.on("destroyed", cleanup);
|
|
18892
|
+
const currentUrl = wc.getURL();
|
|
18893
|
+
if (currentUrl) {
|
|
18894
|
+
void handleUrl(currentUrl);
|
|
18895
|
+
}
|
|
18896
|
+
};
|
|
18795
18897
|
const getActiveHighlightCountSafe = async () => {
|
|
18796
18898
|
const tab = tabManager.getActiveTab();
|
|
18797
18899
|
if (!tab) return 0;
|
|
@@ -19211,7 +19313,8 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
19211
19313
|
trackPremiumFunnel("checkout_clicked");
|
|
19212
19314
|
const result = await getCheckoutUrl(email);
|
|
19213
19315
|
if (result.ok && result.url) {
|
|
19214
|
-
tabManager.createTab(result.url);
|
|
19316
|
+
const tabId = tabManager.createTab(result.url);
|
|
19317
|
+
watchPremiumCheckoutTab(tabId);
|
|
19215
19318
|
}
|
|
19216
19319
|
return result;
|
|
19217
19320
|
});
|
|
@@ -19221,6 +19324,12 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
19221
19324
|
sendToRendererViews(Channels.PREMIUM_UPDATE, state2);
|
|
19222
19325
|
return state2;
|
|
19223
19326
|
});
|
|
19327
|
+
electron.ipcMain.handle(Channels.PREMIUM_TRACK_CONTEXT, (_, step) => {
|
|
19328
|
+
assertString(step, "step");
|
|
19329
|
+
if (step === "chat_banner_viewed" || step === "chat_banner_clicked" || step === "settings_banner_viewed" || step === "settings_banner_clicked" || step === "welcome_banner_clicked" || step === "premium_gate_seen" || step === "premium_gate_clicked" || step === "iteration_limit_seen" || step === "iteration_limit_clicked") {
|
|
19330
|
+
trackPremiumFunnel(step);
|
|
19331
|
+
}
|
|
19332
|
+
});
|
|
19224
19333
|
electron.ipcMain.handle(Channels.PREMIUM_PORTAL, async () => {
|
|
19225
19334
|
trackPremiumFunnel("portal_opened");
|
|
19226
19335
|
const result = await getPortalUrl();
|