@quanta-intellect/vessel-browser 0.1.24 → 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/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: `vessel_${def.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
- "vessel_current_tab",
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 vessel_list_tabs when you only need the focused tab."
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
- "vessel_publish_transcript",
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
- "vessel_clear_transcript",
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
- "vessel_extract_content",
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
- "vessel_read_page",
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
- "vessel_list_tabs",
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
- "vessel_navigate",
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
- "vessel_set_ad_blocking",
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
- "vessel_extract_structured_data",
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
- "vessel_go_back",
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
- "vessel_go_forward",
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
- "vessel_reload",
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
- "vessel_click",
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
- "vessel_hover",
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
- "vessel_focus",
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
- "vessel_extract_text",
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
- "vessel_type",
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
- "vessel_type_text",
15852
+ "type_text",
15822
15853
  {
15823
15854
  title: "Type Text",
15824
- description: "Alias for vessel_type. Type text into an input field or textarea.",
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
- "vessel_select_option",
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
- "vessel_submit_form",
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
- "vessel_press_key",
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
- "vessel_scroll",
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
- "vessel_dismiss_popup",
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
- "vessel_clear_overlays",
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
- "vessel_wait_for",
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
- "vessel_create_tab",
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
- "vessel_switch_tab",
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
- "vessel_close_tab",
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
- "vessel_checkpoint_create",
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
- "vessel_checkpoint_restore",
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
- "vessel_save_session",
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
- "vessel_load_session",
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
- "vessel_list_sessions",
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
- "vessel_delete_session",
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
- "vessel_screenshot",
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
- "vessel_highlight",
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
- "vessel_clear_highlights",
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
- "vessel_list_highlights",
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
- "vessel_remove_highlight",
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 vessel_list_highlights to find IDs.",
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
- "vessel_create_folder",
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
- "vessel_bookmark_save",
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
- "vessel_bookmark_list",
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
- "vessel_bookmark_organize",
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
- "vessel_bookmark_search",
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
- "vessel_bookmark_remove",
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
- "vessel_bookmark_archive",
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
- "vessel_bookmark_open",
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
- "vessel_folder_remove",
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
- "vessel_folder_rename",
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
- "vessel_memory_note_create",
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
- "vessel_memory_append",
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
- "vessel_memory_list",
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
- "vessel_memory_search",
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
- "vessel_memory_page_capture",
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
- "vessel_memory_link_bookmark",
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
- "vessel_flow_start",
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
- "vessel_flow_advance",
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
- "vessel_flow_status",
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
- "vessel_flow_end",
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
- "vessel_suggest",
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 vessel_navigate to open a page."
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 vessel_navigate to a working URL."
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(" → vessel_clear_overlays for stacked modals");
17302
- suggestions.push(" → or vessel_dismiss_popup for a single popup");
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
- " → vessel_login(username, password) — handles the full flow"
17339
+ " → login(username, password) — handles the full flow"
17309
17340
  );
17310
17341
  suggestions.push(
17311
- " → Or vessel_fill_form + vessel_submit_form for manual control"
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
- " → vessel_search(query) — finds the box, types, submits"
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(" → vessel_click on a result link");
17351
+ suggestions.push(" → click on a result link");
17321
17352
  if (hasPagination) {
17322
- suggestions.push(" → vessel_paginate('next') for more results");
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
- " → vessel_fill_form(fields) — fill all fields at once"
17358
+ " → fill_form(fields) — fill all fields at once"
17328
17359
  );
17329
- suggestions.push(" → Or vessel_type for individual fields");
17360
+ suggestions.push(" → Or type for individual fields");
17330
17361
  } else if (hasPagination) {
17331
17362
  suggestions.push("📄 PAGINATED CONTENT:");
17332
- suggestions.push(" → vessel_extract_content to read this page");
17333
- suggestions.push(" → vessel_paginate('next') for the next page");
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(" → vessel_extract_content for readable text");
17337
- suggestions.push(" → vessel_scroll to see more");
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
- " → vessel_extract_content to understand the page structure"
17372
+ " → extract_content to understand the page structure"
17342
17373
  );
17343
- suggestions.push(" → vessel_click on any element by index");
17344
- suggestions.push(" → vessel_navigate to go somewhere new");
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
- "vessel_fill_form",
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
- "vessel_login",
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
- "vessel_search",
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
- "vessel_paginate",
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
- "vessel_accept_cookies",
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
- "vessel_accept_cookies",
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 vessel_dismiss_popup for other overlays.";
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
- "vessel_extract_table",
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
- "vessel_extract_table",
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
- "vessel_scroll_to_element",
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
- "vessel_scroll_to_element",
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
- "vessel_wait_for_navigation",
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
- "vessel_wait_for_navigation",
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
- "vessel_vault_status",
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 vessel_vault_login to fill the login form. Credentials are filled directly — you will NOT see the password values.`
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
- "vessel_vault_login",
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
- "vessel_vault_totp",
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
- "vessel_metrics",
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();