@quanta-intellect/vessel-browser 0.1.28 → 0.1.29

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 CHANGED
@@ -29,7 +29,7 @@ https://github.com/user-attachments/assets/0a72b48a-873a-4eb0-b8f2-23e34d8472c4
29
29
 
30
30
  ## Quick Start
31
31
 
32
- Want the full agent toolkit from day one? [Start a 5-Day Free Trial of Vessel Premium](https://vesselpremium.quantaintellect.com/checkout).
32
+ Want the full agent toolkit from day one? [Start a 7-Day Free Trial of Vessel Premium — $5.99/mo](https://vesselpremium.quantaintellect.com/checkout).
33
33
 
34
34
  ### Fastest Install Today
35
35
 
package/out/main/index.js CHANGED
@@ -8085,20 +8085,21 @@ function pruneToolsForContext(tools, pageType, query = "") {
8085
8085
  const ctx = pageType ?? "GENERAL";
8086
8086
  const hints = CONTEXT_HINTS[ctx] ?? {};
8087
8087
  const intents = inferIntent(query);
8088
- const scored = tools.filter((tool) => !isToolGated(tool.name)).filter((tool) => shouldIncludeTool(tool.name, ctx, intents)).map((tool) => ({
8088
+ const scored = tools.filter((tool) => shouldIncludeTool(tool.name, ctx, intents)).map((tool) => ({
8089
8089
  tool,
8090
8090
  score: scoreForContext(tool.name, ctx)
8091
8091
  }));
8092
8092
  scored.sort((a, b) => a.score - b.score);
8093
8093
  return scored.map(({ tool, score }) => {
8094
+ let description = tool.description ?? "";
8094
8095
  const hint = hints[tool.name];
8095
8096
  if (hint && score <= 20) {
8096
- return {
8097
- ...tool,
8098
- description: hint + tool.description
8099
- };
8097
+ description = hint + description;
8098
+ }
8099
+ if (isToolGated(tool.name)) {
8100
+ description = `[Premium — requires Vessel Premium] ${description}`;
8100
8101
  }
8101
- return tool;
8102
+ return description !== tool.description ? { ...tool, description } : tool;
8102
8103
  });
8103
8104
  }
8104
8105
  function trimText(value) {
@@ -8512,13 +8513,17 @@ function updateBookmark(id, updates) {
8512
8513
  emit();
8513
8514
  return { ...bookmark };
8514
8515
  }
8515
- function removeFolder(id) {
8516
+ function removeFolder(id, deleteContents = false) {
8516
8517
  load();
8517
8518
  const exists = state.folders.some((f) => f.id === id);
8518
8519
  if (!exists) return false;
8519
- state.bookmarks = state.bookmarks.map(
8520
- (b) => b.folderId === id ? { ...b, folderId: UNSORTED_ID } : b
8521
- );
8520
+ if (deleteContents) {
8521
+ state.bookmarks = state.bookmarks.filter((b) => b.folderId !== id);
8522
+ } else {
8523
+ state.bookmarks = state.bookmarks.map(
8524
+ (b) => b.folderId === id ? { ...b, folderId: UNSORTED_ID } : b
8525
+ );
8526
+ }
8522
8527
  state.folders = state.folders.filter((f) => f.id !== id);
8523
8528
  save();
8524
8529
  emit();
@@ -9204,6 +9209,18 @@ async function executePageScript(wc, script, options) {
9204
9209
  }
9205
9210
  }
9206
9211
  }
9212
+ async function waitForJsReady(wc, timeout = 8e3) {
9213
+ const start = Date.now();
9214
+ while (Date.now() - start < timeout) {
9215
+ const ready = await executePageScript(wc, "1", {
9216
+ timeoutMs: 250,
9217
+ userGesture: true,
9218
+ label: "js-ready probe"
9219
+ });
9220
+ if (ready === 1) return;
9221
+ await sleep$1(250);
9222
+ }
9223
+ }
9207
9224
  function waitForLoad$1(wc, timeout = 5e3) {
9208
9225
  return new Promise((resolve) => {
9209
9226
  let finished = false;
@@ -10492,7 +10509,89 @@ async function tryDismissConsentIframe(wc) {
10492
10509
  }
10493
10510
  return null;
10494
10511
  }
10512
+ async function tryAcceptCookiesQuickly(wc) {
10513
+ const dismissed = await executePageScript(
10514
+ wc,
10515
+ `
10516
+ (function() {
10517
+ var selectors = [
10518
+ '#onetrust-accept-btn-handler',
10519
+ '#CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll',
10520
+ '[data-cookiefirst-action="accept"]',
10521
+ '.cookie-consent-accept-all',
10522
+ '#accept-cookies',
10523
+ '.cc-accept',
10524
+ '.cc-btn.cc-allow',
10525
+ '[aria-label="Accept cookies"]',
10526
+ '[aria-label="Accept all cookies"]',
10527
+ '[data-testid="cookie-accept"]',
10528
+ '[data-testid="consent-accept"]',
10529
+ '[data-testid="accept-all"]',
10530
+ 'button[class*="consent"][class*="accept"]',
10531
+ 'button[class*="privacy"][class*="accept"]',
10532
+ '.fc-cta-consent',
10533
+ '#sp_choice_button_accept',
10534
+ '.message-component.message-button.no-children.focusable.sp_choice_type_11',
10535
+ '[class*="truste"] [class*="accept"]',
10536
+ '[id*="consent-accept"]',
10537
+ '[class*="cmp-accept"]',
10538
+ ];
10539
+ var textPatterns = [
10540
+ 'accept all',
10541
+ 'accept cookies',
10542
+ 'allow all',
10543
+ 'allow cookies',
10544
+ 'agree',
10545
+ 'got it',
10546
+ 'ok',
10547
+ 'i agree',
10548
+ 'i accept',
10549
+ 'consent',
10550
+ 'continue',
10551
+ 'accept and continue',
10552
+ 'accept & continue'
10553
+ ];
10554
+ for (var i = 0; i < selectors.length; i++) {
10555
+ var el = document.querySelector(selectors[i]);
10556
+ if (el && el instanceof HTMLElement) {
10557
+ el.click();
10558
+ return "Dismissed cookie banner via: " + selectors[i];
10559
+ }
10560
+ }
10561
+ var buttons = document.querySelectorAll('button, a[role="button"], [type="submit"]');
10562
+ for (var j = 0; j < buttons.length; j++) {
10563
+ var btn = buttons[j];
10564
+ var text = (btn.textContent || '').trim().toLowerCase();
10565
+ for (var k = 0; k < textPatterns.length; k++) {
10566
+ if (text === textPatterns[k] || text.startsWith(textPatterns[k])) {
10567
+ btn.click();
10568
+ return "Dismissed cookie banner via text match: " + text;
10569
+ }
10570
+ }
10571
+ }
10572
+ return null;
10573
+ })()
10574
+ `,
10575
+ {
10576
+ label: "accept cookies",
10577
+ timeoutMs: 1200
10578
+ }
10579
+ );
10580
+ if (dismissed) return dismissed;
10581
+ return tryDismissConsentIframe(wc);
10582
+ }
10495
10583
  async function clearOverlays(wc, strategy = "auto") {
10584
+ const quickCookieResult = await tryAcceptCookiesQuickly(wc);
10585
+ if (quickCookieResult === PAGE_SCRIPT_TIMEOUT) {
10586
+ return pageBusyError("clear_overlays");
10587
+ }
10588
+ if (quickCookieResult) {
10589
+ return [
10590
+ quickCookieResult,
10591
+ "Stopped after a lightweight consent pass to keep the page responsive. Re-run only if the banner is still blocking the page."
10592
+ ].join("\n");
10593
+ }
10594
+ await waitForJsReady(wc, 1500);
10496
10595
  const steps = [];
10497
10596
  let cleared = 0;
10498
10597
  const maxIterations = 8;
@@ -10556,6 +10655,12 @@ Submitted modal: ${submitResult}`;
10556
10655
  actionMessage = `Fallback popup handling: ${await dismissPopup$1(wc)}`;
10557
10656
  }
10558
10657
  steps.push(actionMessage);
10658
+ if (overlay.kind === "cookie_consent") {
10659
+ steps.push(
10660
+ "Stopped after a lightweight consent pass to keep the page responsive. Re-run only if the banner is still blocking the page."
10661
+ );
10662
+ return steps.join("\n");
10663
+ }
10559
10664
  await sleep$1(250);
10560
10665
  const after = await extractContent(wc);
10561
10666
  const afterState = describeOverlayState(after);
@@ -12599,10 +12704,18 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
12599
12704
  (el) => (el.text || "").toLowerCase() === "next" || el.text === "›" || el.text === "»"
12600
12705
  );
12601
12706
  const hasOverlays = page.overlays.some((o) => o.blocksInteraction);
12707
+ const hasCookieConsent = page.overlays.some(
12708
+ (overlay) => overlay.blocksInteraction && overlay.kind === "cookie_consent"
12709
+ );
12602
12710
  if (hasOverlays) {
12603
12711
  suggestions.push("BLOCKING OVERLAY detected — dismiss it first:");
12604
- suggestions.push(" → clear_overlays for stacked modals");
12605
- suggestions.push(" → or dismiss_popup for a single popup");
12712
+ if (hasCookieConsent) {
12713
+ suggestions.push(" → accept_cookies for consent banners");
12714
+ suggestions.push(" → clear_overlays only if consent handling does not unblock the page");
12715
+ } else {
12716
+ suggestions.push(" → clear_overlays for stacked modals");
12717
+ suggestions.push(" → or dismiss_popup for a single popup");
12718
+ }
12606
12719
  suggestions.push("");
12607
12720
  }
12608
12721
  if (hasPasswordField) {
@@ -12807,64 +12920,11 @@ ${steps.join("\n")}`;
12807
12920
  }
12808
12921
  case "accept_cookies": {
12809
12922
  if (!wc) return "Error: No active tab";
12810
- const dismissed = await executePageScript(
12811
- wc,
12812
- `
12813
- (function() {
12814
- // Common cookie consent selectors — OneTrust, CookieBot, GDPR banners
12815
- var selectors = [
12816
- '#onetrust-accept-btn-handler',
12817
- '#CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll',
12818
- '[data-cookiefirst-action="accept"]',
12819
- '.cookie-consent-accept-all',
12820
- '#accept-cookies',
12821
- '.cc-accept',
12822
- '.cc-btn.cc-allow',
12823
- '[aria-label="Accept cookies"]',
12824
- '[aria-label="Accept all cookies"]',
12825
- '[data-testid="cookie-accept"]',
12826
- // CNN / WarnerMedia / common consent SDKs
12827
- '[data-testid="consent-accept"]',
12828
- '[data-testid="accept-all"]',
12829
- 'button[class*="consent"][class*="accept"]',
12830
- 'button[class*="privacy"][class*="accept"]',
12831
- '.fc-cta-consent',
12832
- '#sp_choice_button_accept',
12833
- '.message-component.message-button.no-children.focusable.sp_choice_type_11',
12834
- '[class*="truste"] [class*="accept"]',
12835
- '[id*="consent-accept"]',
12836
- '[class*="cmp-accept"]',
12837
- ];
12838
- // Also try text-matching on buttons
12839
- var textPatterns = ['accept all', 'accept cookies', 'allow all', 'allow cookies', 'agree', 'got it', 'ok', 'i agree', 'i accept', 'consent', 'continue', 'accept and continue', 'accept & continue'];
12840
- for (var i = 0; i < selectors.length; i++) {
12841
- var el = document.querySelector(selectors[i]);
12842
- if (el && el instanceof HTMLElement) { el.click(); return "Dismissed cookie banner via: " + selectors[i]; }
12843
- }
12844
- var buttons = document.querySelectorAll('button, a[role="button"], [type="submit"]');
12845
- for (var j = 0; j < buttons.length; j++) {
12846
- var btn = buttons[j];
12847
- var text = (btn.textContent || '').trim().toLowerCase();
12848
- for (var k = 0; k < textPatterns.length; k++) {
12849
- if (text === textPatterns[k] || text.startsWith(textPatterns[k])) {
12850
- btn.click();
12851
- return "Dismissed cookie banner via text match: " + text;
12852
- }
12853
- }
12854
- }
12855
- return null;
12856
- })()
12857
- `,
12858
- {
12859
- label: "accept cookies"
12860
- }
12861
- );
12923
+ const dismissed = await tryAcceptCookiesQuickly(wc);
12862
12924
  if (dismissed === PAGE_SCRIPT_TIMEOUT) {
12863
12925
  return pageBusyError("accept_cookies");
12864
12926
  }
12865
12927
  if (dismissed) return dismissed;
12866
- const iframeResult = await tryDismissConsentIframe(wc);
12867
- if (iframeResult) return iframeResult;
12868
12928
  return "No cookie consent banner detected. Try dismiss_popup for other overlays.";
12869
12929
  }
12870
12930
  case "extract_table": {
@@ -17216,22 +17276,29 @@ ${JSON.stringify(otherHighlights, null, 2)}`
17216
17276
  "folder_remove",
17217
17277
  {
17218
17278
  title: "Remove Bookmark Folder",
17219
- description: "Remove a folder. Bookmarks in it are moved to Unsorted.",
17279
+ description: "Remove a folder. By default bookmarks in it are moved to Unsorted. Set delete_contents to true to delete them with the folder.",
17220
17280
  inputSchema: {
17221
- folder_id: zod.z.string().describe("ID of the folder to remove")
17281
+ folder_id: zod.z.string().describe("ID of the folder to remove"),
17282
+ delete_contents: zod.z.boolean().optional().default(false).describe(
17283
+ "If true, delete all bookmarks in the folder. If false (default), move them to Unsorted."
17284
+ )
17222
17285
  }
17223
17286
  },
17224
- async ({ folder_id }) => {
17287
+ async ({ folder_id, delete_contents }) => {
17225
17288
  return withAction(
17226
17289
  runtime2,
17227
17290
  tabManager,
17228
17291
  "remove_bookmark_folder",
17229
- { folder_id },
17292
+ { folder_id, delete_contents },
17230
17293
  async () => {
17231
- const removed = removeFolder(folder_id);
17232
- return removed ? composeFolderAwareResponse(
17233
- `Removed folder ${folder_id}. Bookmarks moved to Unsorted.`
17234
- ) : `Folder ${folder_id} not found`;
17294
+ const removed = removeFolder(
17295
+ folder_id,
17296
+ delete_contents
17297
+ );
17298
+ if (!removed) return `Folder ${folder_id} not found`;
17299
+ return composeFolderAwareResponse(
17300
+ delete_contents ? `Removed folder ${folder_id} and deleted its bookmarks.` : `Removed folder ${folder_id}. Bookmarks moved to Unsorted.`
17301
+ );
17235
17302
  }
17236
17303
  );
17237
17304
  }
@@ -19072,7 +19139,53 @@ function assertNumber(value, name) {
19072
19139
  const VALID_APPROVAL_MODES = /* @__PURE__ */ new Set(["auto", "confirm-dangerous", "manual"]);
19073
19140
  function registerIpcHandlers(windowState, runtime2) {
19074
19141
  const { tabManager, chromeView, sidebarView, devtoolsPanelView, mainWindow } = windowState;
19142
+ let sidebarResizeRecoveryTimer = null;
19143
+ let sidebarResizeActive = false;
19144
+ let runtimeUpdateTimer = null;
19145
+ let pendingRuntimeState = null;
19075
19146
  const premiumApiOrigin = process.env.VESSEL_PREMIUM_API ? new URL(process.env.VESSEL_PREMIUM_API).origin : "https://vesselpremium.quantaintellect.com";
19147
+ const clearSidebarResizeRecoveryTimer = () => {
19148
+ if (sidebarResizeRecoveryTimer) {
19149
+ clearTimeout(sidebarResizeRecoveryTimer);
19150
+ sidebarResizeRecoveryTimer = null;
19151
+ }
19152
+ };
19153
+ const restoreSidebarLayoutAfterResize = () => {
19154
+ clearSidebarResizeRecoveryTimer();
19155
+ if (!sidebarResizeActive) return;
19156
+ sidebarResizeActive = false;
19157
+ layoutViews(windowState);
19158
+ };
19159
+ const scheduleSidebarResizeRecovery = () => {
19160
+ clearSidebarResizeRecoveryTimer();
19161
+ sidebarResizeRecoveryTimer = setTimeout(() => {
19162
+ restoreSidebarLayoutAfterResize();
19163
+ }, 1200);
19164
+ };
19165
+ const flushRuntimeUpdate = () => {
19166
+ runtimeUpdateTimer = null;
19167
+ if (!pendingRuntimeState) return;
19168
+ if (!chromeView.webContents.isDestroyed()) {
19169
+ chromeView.webContents.send(
19170
+ Channels.AGENT_RUNTIME_UPDATE,
19171
+ pendingRuntimeState
19172
+ );
19173
+ }
19174
+ if (!sidebarView.webContents.isDestroyed()) {
19175
+ sidebarView.webContents.send(
19176
+ Channels.AGENT_RUNTIME_UPDATE,
19177
+ pendingRuntimeState
19178
+ );
19179
+ }
19180
+ pendingRuntimeState = null;
19181
+ };
19182
+ const scheduleRuntimeUpdate = (state2) => {
19183
+ pendingRuntimeState = state2;
19184
+ if (runtimeUpdateTimer) return;
19185
+ runtimeUpdateTimer = setTimeout(() => {
19186
+ flushRuntimeUpdate();
19187
+ }, 32);
19188
+ };
19076
19189
  const sendToRendererViews = (channel, ...args) => {
19077
19190
  chromeView.webContents.send(channel, ...args);
19078
19191
  sidebarView.webContents.send(channel, ...args);
@@ -19159,7 +19272,7 @@ function registerIpcHandlers(windowState, runtime2) {
19159
19272
  sendToRendererViews(Channels.HIGHLIGHT_COUNT_UPDATE, count);
19160
19273
  };
19161
19274
  runtime2.setUpdateListener((state2) => {
19162
- sendToRendererViews(Channels.AGENT_RUNTIME_UPDATE, state2);
19275
+ scheduleRuntimeUpdate(state2);
19163
19276
  });
19164
19277
  onRuntimeHealthChange((health) => {
19165
19278
  sendToRendererViews(Channels.SETTINGS_HEALTH_UPDATE, health);
@@ -19287,17 +19400,23 @@ function registerIpcHandlers(windowState, runtime2) {
19287
19400
  };
19288
19401
  });
19289
19402
  electron.ipcMain.handle(Channels.SIDEBAR_RESIZE_START, () => {
19403
+ sidebarResizeActive = true;
19404
+ clearSidebarResizeRecoveryTimer();
19290
19405
  const [width, height] = windowState.mainWindow.getContentSize();
19291
19406
  windowState.sidebarView.setBounds({ x: 0, y: 0, width, height });
19407
+ scheduleSidebarResizeRecovery();
19292
19408
  });
19293
19409
  electron.ipcMain.handle(Channels.SIDEBAR_RESIZE, (_, width) => {
19294
19410
  assertNumber(width, "width");
19295
19411
  const clamped = Math.max(240, Math.min(800, Math.round(width)));
19296
19412
  windowState.uiState.sidebarWidth = clamped;
19297
19413
  resizeSidebarViews(windowState);
19414
+ scheduleSidebarResizeRecovery();
19298
19415
  return clamped;
19299
19416
  });
19300
19417
  electron.ipcMain.handle(Channels.SIDEBAR_RESIZE_COMMIT, () => {
19418
+ sidebarResizeActive = false;
19419
+ clearSidebarResizeRecoveryTimer();
19301
19420
  setSetting("sidebarWidth", windowState.uiState.sidebarWidth);
19302
19421
  layoutViews(windowState);
19303
19422
  });
@@ -19389,9 +19508,9 @@ function registerIpcHandlers(windowState, runtime2) {
19389
19508
  trackBookmarkAction("remove");
19390
19509
  return removeBookmark(id);
19391
19510
  });
19392
- electron.ipcMain.handle(Channels.FOLDER_REMOVE, (_, id) => {
19511
+ electron.ipcMain.handle(Channels.FOLDER_REMOVE, (_, id, deleteContents) => {
19393
19512
  trackBookmarkAction("folder_remove");
19394
- return removeFolder(id);
19513
+ return removeFolder(id, deleteContents ?? false);
19395
19514
  });
19396
19515
  electron.ipcMain.handle(
19397
19516
  Channels.FOLDER_RENAME,
@@ -238,7 +238,7 @@ const api = {
238
238
  removeBookmark: (id) => electron.ipcRenderer.invoke(Channels.BOOKMARK_REMOVE, id),
239
239
  createFolder: (name) => electron.ipcRenderer.invoke(Channels.FOLDER_CREATE, name),
240
240
  createFolderWithSummary: (name, summary) => electron.ipcRenderer.invoke(Channels.FOLDER_CREATE, name, summary),
241
- removeFolder: (id) => electron.ipcRenderer.invoke(Channels.FOLDER_REMOVE, id),
241
+ removeFolder: (id, deleteContents) => electron.ipcRenderer.invoke(Channels.FOLDER_REMOVE, id, deleteContents),
242
242
  renameFolder: (id, newName, summary) => electron.ipcRenderer.invoke(Channels.FOLDER_RENAME, id, newName, summary),
243
243
  onAddContextToChat: (cb) => {
244
244
  const handler = (_, bookmarkId) => cb(bookmarkId);
@@ -1818,14 +1818,28 @@ const [focusMode, setFocusMode] = createSignal(false);
1818
1818
  const [commandBarOpen, setCommandBarOpen] = createSignal(false);
1819
1819
  const [settingsOpen, setSettingsOpen] = createSignal(false);
1820
1820
  const [devtoolsPanelOpen, setDevtoolsPanelOpen] = createSignal(false);
1821
- let resizeRafId = null;
1822
1821
  let pendingWidth = null;
1823
- function flushResize() {
1824
- if (pendingWidth !== null) {
1825
- window.vessel.ui.resizeSidebar(pendingWidth);
1826
- pendingWidth = null;
1822
+ let resizeInFlight = null;
1823
+ async function flushResize() {
1824
+ if (resizeInFlight) {
1825
+ await resizeInFlight;
1826
+ if (pendingWidth !== null) {
1827
+ return flushResize();
1828
+ }
1829
+ return;
1830
+ }
1831
+ resizeInFlight = (async () => {
1832
+ while (pendingWidth !== null) {
1833
+ const nextWidth = pendingWidth;
1834
+ pendingWidth = null;
1835
+ await window.vessel.ui.resizeSidebar(nextWidth);
1836
+ }
1837
+ })();
1838
+ try {
1839
+ await resizeInFlight;
1840
+ } finally {
1841
+ resizeInFlight = null;
1827
1842
  }
1828
- resizeRafId = null;
1829
1843
  }
1830
1844
  function useUI() {
1831
1845
  return {
@@ -1847,20 +1861,12 @@ function useUI() {
1847
1861
  );
1848
1862
  setSidebarWidth(clamped);
1849
1863
  pendingWidth = clamped;
1850
- if (resizeRafId === null) {
1851
- resizeRafId = requestAnimationFrame(flushResize);
1852
- }
1864
+ void flushResize();
1853
1865
  },
1854
- commitResize: () => {
1855
- if (resizeRafId !== null) {
1856
- cancelAnimationFrame(resizeRafId);
1857
- resizeRafId = null;
1858
- }
1859
- if (pendingWidth !== null) {
1860
- window.vessel.ui.resizeSidebar(pendingWidth);
1861
- pendingWidth = null;
1862
- }
1863
- window.vessel.ui.commitSidebarResize();
1866
+ commitResize: async () => {
1867
+ pendingWidth = sidebarWidth();
1868
+ await flushResize();
1869
+ await window.vessel.ui.commitSidebarResize();
1864
1870
  },
1865
1871
  toggleFocusMode: async () => {
1866
1872
  const result = await window.vessel.ui.toggleFocusMode();
@@ -2600,7 +2606,7 @@ function useBookmarks() {
2600
2606
  removeBookmark: (id) => window.vessel.bookmarks.removeBookmark(id),
2601
2607
  createFolder: (name) => window.vessel.bookmarks.createFolder(name),
2602
2608
  createFolderWithSummary: (name, summary) => window.vessel.bookmarks.createFolderWithSummary(name, summary),
2603
- removeFolder: (id) => window.vessel.bookmarks.removeFolder(id),
2609
+ removeFolder: (id, deleteContents) => window.vessel.bookmarks.removeFolder(id, deleteContents),
2604
2610
  renameFolder: (id, newName, summary) => window.vessel.bookmarks.renameFolder(id, newName, summary)
2605
2611
  };
2606
2612
  }
@@ -4517,7 +4523,7 @@ function renderKitPrompt(kit, values) {
4517
4523
  (_, key) => values[key] ?? ""
4518
4524
  );
4519
4525
  }
4520
- var _tmpl$$5 = /* @__PURE__ */ template(`<div class=kit-upsell><div class=kit-upsell-icon aria-hidden=true></div><p class=kit-upsell-title>Vessel Premium</p><p class=kit-upsell-body>Automation Kits are a premium feature. Upgrade to unlock pre-built workflows you can launch with one click.</p><button class="agent-primary-button kit-upsell-btn"type=button>Upgrade to Premium`), _tmpl$2$5 = /* @__PURE__ */ template(`<div class=kit-list-header><span class=agent-panel-title>Automation Kits <span class=kit-beta-tag>Beta</span></span><div class=kit-list-header-actions><span class=kit-list-count> kits</span><button class=kit-install-btn type=button title="Install a kit from a .kit.json file">+ Install`), _tmpl$3$4 = /* @__PURE__ */ template(`<div class=kit-install-error><span></span><button class=kit-install-error-dismiss type=button aria-label=Dismiss>×`), _tmpl$4$4 = /* @__PURE__ */ template(`<div class=kit-list>`), _tmpl$5$4 = /* @__PURE__ */ template(`<div class=kit-sched-section><span>Scheduled</span><span class=kit-list-count>`), _tmpl$6$4 = /* @__PURE__ */ template(`<div class=kit-sched-list>`), _tmpl$7$3 = /* @__PURE__ */ template(`<div class=kit-sched-section><span>Recent Activity</span><span class=kit-list-count>`), _tmpl$8$3 = /* @__PURE__ */ template(`<div class=kit-activity-list>`), _tmpl$9$3 = /* @__PURE__ */ template(`<div class=kit-form-header><button class=kit-back-btn type=button title="Back to kits"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><path d="M9 11L5 7l4-4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg>Back</button><div class=kit-form-title>`), _tmpl$0$3 = /* @__PURE__ */ template(`<p class=kit-form-desc>`), _tmpl$1$3 = /* @__PURE__ */ template(`<div class=kit-form-fields>`), _tmpl$10$3 = /* @__PURE__ */ template(`<p class=kit-form-estimate>Estimated run time: ~<!> min`), _tmpl$11$3 = /* @__PURE__ */ template(`<button class="agent-primary-button kit-run-btn"type=button>`), _tmpl$12$3 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label class=kit-form-label>Date &amp; time</label><input class=kit-form-input type=datetime-local>`), _tmpl$13$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label class=kit-form-label>Time of day</label><input class="kit-form-input kit-schedule-time"type=time>`), _tmpl$14$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label class=kit-form-label>Day</label><select class=kit-form-input>`), _tmpl$15$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label class=kit-form-label>Time</label><input class="kit-form-input kit-schedule-time"type=time>`), _tmpl$16$2 = /* @__PURE__ */ template(`<p class=kit-schedule-error>`), _tmpl$17$2 = /* @__PURE__ */ template(`<div class=kit-schedule-form><div class=kit-schedule-types></div><p class=kit-schedule-note>Schedules run only while Vessel is open. Missed runs are skipped.</p><button class="agent-primary-button kit-schedule-btn"type=button>`), _tmpl$18$2 = /* @__PURE__ */ template(`<div class=kit-schedule-section><label class=kit-schedule-toggle><input type=checkbox>Schedule for later`), _tmpl$19$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label>Run at</label><input type=datetime-local class="kit-form-input kit-schedule-time">`), _tmpl$20$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label>Day</label><select class="kit-form-input kit-schedule-time">`), _tmpl$21$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label>Time</label><input type=time class="kit-form-input kit-schedule-time">`), _tmpl$22$2 = /* @__PURE__ */ template(`<div class=sched-edit-backdrop><div class=sched-edit-panel><div class=sched-edit-header><span class=sched-edit-title>Edit schedule</span><span class=sched-edit-job-name></span></div><div class=kit-schedule-types></div><div class=sched-edit-actions><button class=kit-back-btn type=button>Cancel</button><button class=agent-primary-button type=button>Save`), _tmpl$23$2 = /* @__PURE__ */ template(`<section class=automation-panel>`), _tmpl$24$2 = /* @__PURE__ */ template(`<div class=kit-card-meta>~<!> min`), _tmpl$25$2 = /* @__PURE__ */ template(`<button class=kit-remove-btn type=button>×`), _tmpl$26$2 = /* @__PURE__ */ template(`<div class=kit-card role=button tabindex=0><span class=kit-card-icon aria-hidden=true></span><div class=kit-card-body><div class=kit-card-name></div><div class=kit-card-desc>`), _tmpl$27$2 = /* @__PURE__ */ template(`<svg class=kit-card-caret width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><path d="M5 3l4 4-4 4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round>`), _tmpl$28$2 = /* @__PURE__ */ template(`<div class=kit-sched-next>Next: `), _tmpl$29$2 = /* @__PURE__ */ template(`<div class=sched-context-menu><button class=sched-ctx-item type=button>Edit task</button><button class=sched-ctx-item type=button>Edit schedule</button><div class=sched-ctx-divider></div><button class=sched-ctx-item type=button></button><button class="sched-ctx-item sched-ctx-danger"type=button>Delete`), _tmpl$30$2 = /* @__PURE__ */ template(`<div class=kit-sched-card><span class="kit-card-icon kit-sched-icon"aria-hidden=true></span><div class=kit-sched-body><div class=kit-sched-name></div><div class=kit-sched-meta></div></div><div class=kit-sched-actions><button class=kit-sched-toggle type=button></button><button class=kit-remove-btn type=button title="Delete schedule"aria-label="Delete schedule">×`), _tmpl$31$2 = /* @__PURE__ */ template(`<div class=kit-activity-output>`), _tmpl$32$1 = /* @__PURE__ */ template(`<div class=kit-activity-card><div class=kit-activity-header><div class=kit-activity-title><span class="kit-card-icon kit-sched-icon"aria-hidden=true></span><div class=kit-activity-title-copy><div class=kit-sched-name></div><div class=kit-activity-time></div></div></div><span class=kit-activity-badge>`), _tmpl$33$1 = /* @__PURE__ */ template(`<div class="kit-activity-output kit-activity-placeholder">`), _tmpl$34$1 = /* @__PURE__ */ template(`<span class=kit-form-required aria-hidden=true>*`), _tmpl$35$1 = /* @__PURE__ */ template(`<textarea class=kit-form-textarea rows=3>`), _tmpl$36$1 = /* @__PURE__ */ template(`<p class=kit-form-hint>`), _tmpl$37$1 = /* @__PURE__ */ template(`<div class=kit-form-field><label class=kit-form-label>`), _tmpl$38$1 = /* @__PURE__ */ template(`<input class=kit-form-input>`), _tmpl$39$1 = /* @__PURE__ */ template(`<span class=kit-run-spinner aria-hidden=true>`), _tmpl$40$1 = /* @__PURE__ */ template(`<label class=kit-schedule-type-option><input type=radio name=sched-type>`), _tmpl$41$1 = /* @__PURE__ */ template(`<option>`), _tmpl$42$1 = /* @__PURE__ */ template(`<label class=kit-schedule-type-option><input type=radio name=edit-sched-type>`);
4526
+ var _tmpl$$5 = /* @__PURE__ */ template(`<div class=kit-upsell><div class=kit-upsell-icon aria-hidden=true></div><p class=kit-upsell-title>Vessel Premium</p><p class=kit-upsell-body>Automation Kits are a premium feature. Upgrade to unlock pre-built workflows you can launch with one click.</p><button class="agent-primary-button kit-upsell-btn"type=button>Start 7-day free trial — $5.99/mo after`), _tmpl$2$5 = /* @__PURE__ */ template(`<div class=kit-list-header><span class=agent-panel-title>Automation Kits <span class=kit-beta-tag>Beta</span></span><div class=kit-list-header-actions><span class=kit-list-count> kits</span><button class=kit-install-btn type=button title="Install a kit from a .kit.json file">+ Install`), _tmpl$3$4 = /* @__PURE__ */ template(`<div class=kit-install-error><span></span><button class=kit-install-error-dismiss type=button aria-label=Dismiss>×`), _tmpl$4$4 = /* @__PURE__ */ template(`<div class=kit-list>`), _tmpl$5$4 = /* @__PURE__ */ template(`<div class=kit-sched-section><span>Scheduled</span><span class=kit-list-count>`), _tmpl$6$4 = /* @__PURE__ */ template(`<div class=kit-sched-list>`), _tmpl$7$3 = /* @__PURE__ */ template(`<div class=kit-sched-section><span>Recent Activity</span><span class=kit-list-count>`), _tmpl$8$3 = /* @__PURE__ */ template(`<div class=kit-activity-list>`), _tmpl$9$3 = /* @__PURE__ */ template(`<div class=kit-form-header><button class=kit-back-btn type=button title="Back to kits"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><path d="M9 11L5 7l4-4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg>Back</button><div class=kit-form-title>`), _tmpl$0$3 = /* @__PURE__ */ template(`<p class=kit-form-desc>`), _tmpl$1$3 = /* @__PURE__ */ template(`<div class=kit-form-fields>`), _tmpl$10$3 = /* @__PURE__ */ template(`<p class=kit-form-estimate>Estimated run time: ~<!> min`), _tmpl$11$3 = /* @__PURE__ */ template(`<button class="agent-primary-button kit-run-btn"type=button>`), _tmpl$12$3 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label class=kit-form-label>Date &amp; time</label><input class=kit-form-input type=datetime-local>`), _tmpl$13$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label class=kit-form-label>Time of day</label><input class="kit-form-input kit-schedule-time"type=time>`), _tmpl$14$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label class=kit-form-label>Day</label><select class=kit-form-input>`), _tmpl$15$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label class=kit-form-label>Time</label><input class="kit-form-input kit-schedule-time"type=time>`), _tmpl$16$2 = /* @__PURE__ */ template(`<p class=kit-schedule-error>`), _tmpl$17$2 = /* @__PURE__ */ template(`<div class=kit-schedule-form><div class=kit-schedule-types></div><p class=kit-schedule-note>Schedules run only while Vessel is open. Missed runs are skipped.</p><button class="agent-primary-button kit-schedule-btn"type=button>`), _tmpl$18$2 = /* @__PURE__ */ template(`<div class=kit-schedule-section><label class=kit-schedule-toggle><input type=checkbox>Schedule for later`), _tmpl$19$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label>Run at</label><input type=datetime-local class="kit-form-input kit-schedule-time">`), _tmpl$20$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label>Day</label><select class="kit-form-input kit-schedule-time">`), _tmpl$21$2 = /* @__PURE__ */ template(`<div class=kit-schedule-row><label>Time</label><input type=time class="kit-form-input kit-schedule-time">`), _tmpl$22$2 = /* @__PURE__ */ template(`<div class=sched-edit-backdrop><div class=sched-edit-panel><div class=sched-edit-header><span class=sched-edit-title>Edit schedule</span><span class=sched-edit-job-name></span></div><div class=kit-schedule-types></div><div class=sched-edit-actions><button class=kit-back-btn type=button>Cancel</button><button class=agent-primary-button type=button>Save`), _tmpl$23$2 = /* @__PURE__ */ template(`<section class=automation-panel>`), _tmpl$24$2 = /* @__PURE__ */ template(`<div class=kit-card-meta>~<!> min`), _tmpl$25$2 = /* @__PURE__ */ template(`<button class=kit-remove-btn type=button>×`), _tmpl$26$2 = /* @__PURE__ */ template(`<div class=kit-card role=button tabindex=0><span class=kit-card-icon aria-hidden=true></span><div class=kit-card-body><div class=kit-card-name></div><div class=kit-card-desc>`), _tmpl$27$2 = /* @__PURE__ */ template(`<svg class=kit-card-caret width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><path d="M5 3l4 4-4 4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round>`), _tmpl$28$2 = /* @__PURE__ */ template(`<div class=kit-sched-next>Next: `), _tmpl$29$2 = /* @__PURE__ */ template(`<div class=sched-context-menu><button class=sched-ctx-item type=button>Edit task</button><button class=sched-ctx-item type=button>Edit schedule</button><div class=sched-ctx-divider></div><button class=sched-ctx-item type=button></button><button class="sched-ctx-item sched-ctx-danger"type=button>Delete`), _tmpl$30$2 = /* @__PURE__ */ template(`<div class=kit-sched-card><span class="kit-card-icon kit-sched-icon"aria-hidden=true></span><div class=kit-sched-body><div class=kit-sched-name></div><div class=kit-sched-meta></div></div><div class=kit-sched-actions><button class=kit-sched-toggle type=button></button><button class=kit-remove-btn type=button title="Delete schedule"aria-label="Delete schedule">×`), _tmpl$31$2 = /* @__PURE__ */ template(`<div class=kit-activity-output>`), _tmpl$32$1 = /* @__PURE__ */ template(`<div class=kit-activity-card><div class=kit-activity-header><div class=kit-activity-title><span class="kit-card-icon kit-sched-icon"aria-hidden=true></span><div class=kit-activity-title-copy><div class=kit-sched-name></div><div class=kit-activity-time></div></div></div><span class=kit-activity-badge>`), _tmpl$33$1 = /* @__PURE__ */ template(`<div class="kit-activity-output kit-activity-placeholder">`), _tmpl$34$1 = /* @__PURE__ */ template(`<span class=kit-form-required aria-hidden=true>*`), _tmpl$35$1 = /* @__PURE__ */ template(`<textarea class=kit-form-textarea rows=3>`), _tmpl$36$1 = /* @__PURE__ */ template(`<p class=kit-form-hint>`), _tmpl$37$1 = /* @__PURE__ */ template(`<div class=kit-form-field><label class=kit-form-label>`), _tmpl$38$1 = /* @__PURE__ */ template(`<input class=kit-form-input>`), _tmpl$39$1 = /* @__PURE__ */ template(`<span class=kit-run-spinner aria-hidden=true>`), _tmpl$40$1 = /* @__PURE__ */ template(`<label class=kit-schedule-type-option><input type=radio name=sched-type>`), _tmpl$41$1 = /* @__PURE__ */ template(`<option>`), _tmpl$42$1 = /* @__PURE__ */ template(`<label class=kit-schedule-type-option><input type=radio name=edit-sched-type>`);
4521
4527
  const ICON_MAP = {
4522
4528
  BookOpen: book_open_default,
4523
4529
  Tag: tag_default,
@@ -5355,7 +5361,7 @@ const AutomationTab = (props) => {
5355
5361
  };
5356
5362
  delegateEvents(["click", "input", "keydown", "contextmenu"]);
5357
5363
  const vesselLogo = "" + new URL("vessel-logo-transparent-IT25qr-Z.png", import.meta.url).href;
5358
- var _tmpl$$4 = /* @__PURE__ */ template(`<div class="message-content markdown-content">`), _tmpl$2$4 = /* @__PURE__ */ template(`<div class=premium-inline-offer><div class=premium-inline-kicker>Vessel Premium</div><div class=premium-inline-title></div><p class=premium-inline-copy></p><div class=premium-inline-actions><button class="agent-primary-button premium-inline-primary"type=button>Start free trial</button><button class="agent-control-button premium-inline-secondary"type=button>View details`), _tmpl$3$3 = /* @__PURE__ */ template(`<span class=sidebar-tab-badge>`), _tmpl$4$3 = /* @__PURE__ */ template(`<div class=agent-section-title>Pending approvals`), _tmpl$5$3 = /* @__PURE__ */ template(`<button class=agent-section-toggle type=button>`), _tmpl$6$3 = /* @__PURE__ */ template(`<section class=agent-panel><div class=agent-panel-header><div><div class=agent-panel-title>Supervisor</div><div class=agent-panel-subtitle></div></div><span class=agent-status-pill></span></div><div class=agent-panel-controls><button class=agent-control-button type=button></button><button class=agent-control-button type=button>Restore session</button></div><div class=agent-muted></div><div class=agent-section-header><div class=agent-section-title>Recent actions`), _tmpl$7$2 = /* @__PURE__ */ template(`<span class=bookmark-status-pill>Saved`), _tmpl$8$2 = /* @__PURE__ */ template(`<div class=bookmark-save-card><div class=bookmark-current-title></div><div class=bookmark-current-url></div><div class=bookmark-save-controls><button class=bookmark-primary-button type=button>Save page</button></div><textarea class=bookmark-note-input placeholder="Optional note about why this matters"rows=2>`), _tmpl$9$2 = /* @__PURE__ */ template(`<section class=bookmark-panel><div class=bookmark-panel-header><div><div class=bookmark-panel-title>Bookmarks</div><div class=bookmark-panel-subtitle></div></div></div><input class="bookmark-input bookmark-search-input"placeholder="Search titles, URLs, notes, and folders"><div class=bookmark-save-shell><button class=bookmark-save-toggle type=button><span class=bookmark-save-toggle-copy><span class=bookmark-save-toggle-title>Save Current Page</span><span class=bookmark-save-toggle-subtitle>Manual bookmark save options</span></span><span class=bookmark-save-toggle-caret aria-hidden=true>▾</span></button></div><form class=bookmark-folder-create><div class=bookmark-folder-form-fields><input class=bookmark-input placeholder="Create a folder"><input class=bookmark-input placeholder="Optional one-line summary"></div><button class=bookmark-secondary-button type=submit>New folder</button></form><div class=bookmark-folder-list>`), _tmpl$0$2 = /* @__PURE__ */ template(`<div class=checkpoint-timeline>`), _tmpl$1$2 = /* @__PURE__ */ template(`<section class="agent-panel checkpoint-panel"><div class=agent-panel-header><div><div class=agent-panel-title>Checkpoints</div><div class=agent-panel-subtitle></div></div></div><div class=agent-panel-body><div class=agent-checkpoint-row><input class=agent-input placeholder="Checkpoint name"><button class=agent-primary-button type=button>Save checkpoint</button></div><div class=agent-section-title>Recent checkpoints`), _tmpl$10$2 = /* @__PURE__ */ template(`<div class="kit-upsell premium-chat-banner"><p class=kit-upsell-title>Vessel Premium</p><p class="kit-upsell-body premium-chat-banner-body">Give the built-in agent a bigger toolbox and longer runway: screenshots, saved sessions, workflow tracking, table extraction, and up to 1,000 tool calls per turn.</p><div class="premium-inline-actions premium-chat-banner-actions"><button class="agent-primary-button premium-inline-primary"type=button>Start free trial</button><button class="agent-control-button premium-inline-secondary"type=button>See Premium`), _tmpl$11$2 = /* @__PURE__ */ template(`<span>`), _tmpl$12$2 = /* @__PURE__ */ template(`<div><div class=streaming-status><span class=streaming-pulse aria-hidden=true></span><span>Generating`), _tmpl$13$1 = /* @__PURE__ */ template(`<div class="message message-assistant"><div class=message-content>`), _tmpl$14$1 = /* @__PURE__ */ template(`<div class=sidebar-empty><svg class=sidebar-empty-icon width=48 height=48 viewBox="0 0 48 48"aria-hidden=true><line x1=8 y1=8 x2=24 y2=5 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=24 y1=5 x2=40 y2=10 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=8 y1=8 x2=6 y2=24 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=40 y1=10 x2=44 y2=26 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=6 y1=24 x2=10 y2=38 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=44 y1=26 x2=38 y2=40 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=10 y1=38 x2=24 y2=44 stroke=var(--border-visible) stroke-width=1 opacity=0.35></line><line x1=38 y1=40 x2=24 y2=44 stroke=var(--border-visible) stroke-width=1 opacity=0.35></line><line x1=8 y1=8 x2=20 y2=18 stroke=var(--border-visible) stroke-width=1 opacity=0.5></line><line x1=24 y1=5 x2=20 y2=18 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=40 y1=10 x2=32 y2=20 stroke=var(--border-visible) stroke-width=1 opacity=0.5></line><line x1=20 y1=18 x2=32 y2=20 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.3></line><line x1=6 y1=24 x2=18 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=20 y1=18 x2=18 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=32 y1=20 x2=36 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=44 y1=26 x2=36 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=18 y1=30 x2=36 y2=30 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.25></line><line x1=18 y1=30 x2=10 y2=38 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=36 y1=30 x2=38 y2=40 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=18 y1=30 x2=24 y2=44 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.2></line><line x1=36 y1=30 x2=24 y2=44 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.2></line><circle cx=8 cy=8 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.55></circle><circle cx=24 cy=5 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.45></circle><circle cx=40 cy=10 r=3 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.7></circle><circle cx=6 cy=24 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=44 cy=26 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.55></circle><circle cx=10 cy=38 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=38 cy=40 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.45></circle><circle cx=24 cy=44 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=20 cy=18 r=3.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.85></circle><circle cx=32 cy=20 r=4 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.9></circle><circle cx=18 cy=30 r=3 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.75></circle><circle cx=36 cy=30 r=3.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.8></circle></svg><p class=sidebar-empty-title>Your move.</p><p class=sidebar-empty-hint>Configure a provider in Settings (Ctrl+,) then ask anything about the current page or beyond.`), _tmpl$15$1 = /* @__PURE__ */ template(`<button class=chat-action-btn title="Stop generating"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><rect x=2 y=2 width=10 height=10 rx=1.5 fill=currentColor></rect></svg>Stop`), _tmpl$16$1 = /* @__PURE__ */ template(`<button class=chat-action-btn title="Retry last prompt"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><path d="M11.5 7a4.5 4.5 0 1 1-1.3-3.2"stroke=currentColor stroke-width=1.5 stroke-linecap=round></path><path d="M10.5 1v3h-3"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg>Retry`), _tmpl$17$1 = /* @__PURE__ */ template(`<div class=chat-actions>`), _tmpl$18$1 = /* @__PURE__ */ template(`<div class=highlight-nav><button class=highlight-nav-btn type=button title="Previous highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><path d="M8 10L4 6l4-4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button><button class=highlight-nav-label type=button title="Go to current highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><circle cx=6 cy=6 r=3 fill="rgba(196, 160, 90, 0.6)"stroke="rgba(196, 160, 90, 0.9)"stroke-width=1></circle></svg></button><button class=highlight-nav-btn type=button title="Next highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><path d="M4 2l4 4-4 4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round>`), _tmpl$19$1 = /* @__PURE__ */ template(`<button class=chat-queue-clear type=button>Clear queue`), _tmpl$20$1 = /* @__PURE__ */ template(`<div class=chat-queue-list>`), _tmpl$21$1 = /* @__PURE__ */ template(`<div class=chat-queue-status><div class=chat-queue-status-row><span>`), _tmpl$22$1 = /* @__PURE__ */ template(`<div class=sidebar-input-area><textarea class=sidebar-input rows=2></textarea><button class=sidebar-send>`), _tmpl$23$1 = /* @__PURE__ */ template(`<div class=sidebar><div class=sidebar-resize-handle></div><div class=sidebar-header><div class=sidebar-brand><img class=sidebar-logo alt=Vessel><span class=sidebar-brand-text>Vessel Browser</span></div><div class=sidebar-header-actions><button class=sidebar-clear title="Clear chat">Clear</button><button class=sidebar-close title="Close AI chat (Esc)"aria-label="Close AI chat"><svg width=14 height=14 viewBox="0 0 14 14"aria-hidden=true><path d="M3.5 3.5l7 7M10.5 3.5l-7 7"fill=none stroke=currentColor stroke-width=1.4 stroke-linecap=round></path></svg></button></div></div><div class=sidebar-tabs role=tablist><button class=sidebar-tab role=tab>Supervisor</button><button class=sidebar-tab role=tab>Bookmarks</button><button class=sidebar-tab role=tab>Checkpoints</button><button class=sidebar-tab role=tab>Chat</button><button class=sidebar-tab role=tab>Automate</button></div><div class=sidebar-messages><div>`), _tmpl$24$1 = /* @__PURE__ */ template(`<div class=agent-muted>No pending approvals.`), _tmpl$25$1 = /* @__PURE__ */ template(`<div class="agent-card agent-card-approval"><div class=agent-card-approval-stripe aria-hidden=true></div><div class=agent-card-title></div><div class=agent-card-copy></div><div class=agent-card-copy></div><div class=agent-card-actions><button class=agent-primary-button type=button>Approve</button><button class=agent-control-button type=button>Reject`), _tmpl$26$1 = /* @__PURE__ */ template(`<div class=agent-muted>No actions yet.`), _tmpl$27$1 = /* @__PURE__ */ template(`<div class=agent-muted>Recent actions are collapsed to reduce noise.`), _tmpl$28$1 = /* @__PURE__ */ template(`<div class="agent-card-copy success">`), _tmpl$29$1 = /* @__PURE__ */ template(`<div class="agent-card-copy error">`), _tmpl$30$1 = /* @__PURE__ */ template(`<div class=agent-card><div class=agent-action-row><span class=agent-card-title></span><span></span></div><div class=agent-card-copy>`), _tmpl$31$1 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>`), _tmpl$32 = /* @__PURE__ */ template(`<div class=bookmark-folder-summary>`), _tmpl$33 = /* @__PURE__ */ template(`<div class=bookmark-folder-actions><button class=bookmark-ghost-button type=button>Rename</button><button class="bookmark-ghost-button danger"type=button>Delete`), _tmpl$34 = /* @__PURE__ */ template(`<div class=bookmark-folder-edit><div class=bookmark-folder-form-fields><input class=bookmark-input><input class=bookmark-input placeholder="Optional one-line summary"></div><button class=bookmark-secondary-button type=button>Save</button><button class=bookmark-ghost-button type=button>Cancel`), _tmpl$35 = /* @__PURE__ */ template(`<div class=bookmark-items>`), _tmpl$36 = /* @__PURE__ */ template(`<div class=bookmark-folder-section><div class="bookmark-folder-header clickable"role=button tabindex=0><div class=bookmark-folder-overview><span class=bookmark-folder-chevron aria-hidden=true>▸</span><div><div class=bookmark-folder-name></div><div class=bookmark-folder-meta> saved`), _tmpl$37 = /* @__PURE__ */ template(`<div class=bookmark-folder-collapsed-hint>Click to view saved links.`), _tmpl$38 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>No bookmarks in this folder yet.`), _tmpl$39 = /* @__PURE__ */ template(`<div class=bookmark-item-note>`), _tmpl$40 = /* @__PURE__ */ template(`<div class=bookmark-item><button class=bookmark-item-link type=button><span class=bookmark-item-title></span><span class=bookmark-item-url></span></button><div class=bookmark-item-footer><span class=bookmark-item-time></span><button class="bookmark-ghost-button danger"type=button>Remove`), _tmpl$41 = /* @__PURE__ */ template(`<div class=agent-muted>No checkpoints yet.`), _tmpl$42 = /* @__PURE__ */ template(`<span class=checkpoint-timeline-line>`), _tmpl$43 = /* @__PURE__ */ template(`<div class=checkpoint-timeline-item><div class=checkpoint-timeline-rail><span class=checkpoint-timeline-dot></span></div><div class=checkpoint-timeline-content><div class=checkpoint-timeline-name></div><div class=checkpoint-timeline-time></div><button class=agent-control-button type=button>Restore`), _tmpl$44 = /* @__PURE__ */ template(`<div>`), _tmpl$45 = /* @__PURE__ */ template(`<div class=thinking-state><div class=thinking-orb aria-hidden=true><span></span><span></span><span></span></div><div class=thinking-copy><div class=thinking-title>Thinking`), _tmpl$46 = /* @__PURE__ */ template(`<div class=chat-approval-detail>`), _tmpl$47 = /* @__PURE__ */ template(`<div class=chat-approval><div class=chat-approval-icon aria-hidden=true><svg width=16 height=16 viewBox="0 0 16 16"fill=none><path d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM7.25 4.75a.75.75 0 011.5 0v3.5a.75.75 0 01-1.5 0v-3.5zM8 11.5a.75.75 0 110-1.5.75.75 0 010 1.5z"fill=currentColor></path></svg></div><div class=chat-approval-body><div class=chat-approval-title>Approval needed: <strong></strong></div><div class=chat-approval-detail></div><div class=chat-approval-actions><button class="chat-approval-btn chat-approval-approve"type=button>Approve</button><button class="chat-approval-btn chat-approval-reject"type=button>Reject`), _tmpl$48 = /* @__PURE__ */ template(`<div class=chat-queue-item><span class=chat-queue-text></span><button class=chat-queue-remove type=button>×`);
5364
+ var _tmpl$$4 = /* @__PURE__ */ template(`<div class="message-content markdown-content">`), _tmpl$2$4 = /* @__PURE__ */ template(`<div class=premium-inline-offer><div class=premium-inline-kicker>Vessel Premium</div><div class=premium-inline-title></div><p class=premium-inline-copy></p><div class=premium-inline-actions><button class="agent-primary-button premium-inline-primary"type=button>Start 7-day free trial — $5.99/mo after</button><button class="agent-control-button premium-inline-secondary"type=button>View details`), _tmpl$3$3 = /* @__PURE__ */ template(`<span class=sidebar-tab-badge>`), _tmpl$4$3 = /* @__PURE__ */ template(`<div class=agent-section-title>Pending approvals`), _tmpl$5$3 = /* @__PURE__ */ template(`<button class=agent-section-toggle type=button>`), _tmpl$6$3 = /* @__PURE__ */ template(`<section class=agent-panel><div class=agent-panel-header><div><div class=agent-panel-title>Supervisor</div><div class=agent-panel-subtitle></div></div><span class=agent-status-pill></span></div><div class=agent-panel-controls><button class=agent-control-button type=button></button><button class=agent-control-button type=button>Restore session</button></div><div class=agent-muted></div><div class=agent-section-header><div class=agent-section-title>Recent actions`), _tmpl$7$2 = /* @__PURE__ */ template(`<span class=bookmark-status-pill>Saved`), _tmpl$8$2 = /* @__PURE__ */ template(`<div class=bookmark-save-card><div class=bookmark-current-title></div><div class=bookmark-current-url></div><div class=bookmark-save-controls><button class=bookmark-primary-button type=button>Save page</button></div><textarea class=bookmark-note-input placeholder="Optional note about why this matters"rows=2>`), _tmpl$9$2 = /* @__PURE__ */ template(`<section class=bookmark-panel><div class=bookmark-panel-header><div><div class=bookmark-panel-title>Bookmarks</div><div class=bookmark-panel-subtitle></div></div></div><input class="bookmark-input bookmark-search-input"placeholder="Search titles, URLs, notes, and folders"><div class=bookmark-save-shell><button class=bookmark-save-toggle type=button><span class=bookmark-save-toggle-copy><span class=bookmark-save-toggle-title>Save Current Page</span><span class=bookmark-save-toggle-subtitle>Manual bookmark save options</span></span><span class=bookmark-save-toggle-caret aria-hidden=true>▾</span></button></div><form class=bookmark-folder-create><div class=bookmark-folder-form-fields><input class=bookmark-input placeholder="Create a folder"><input class=bookmark-input placeholder="Optional one-line summary"></div><button class=bookmark-secondary-button type=submit>New folder</button></form><div class=bookmark-folder-list>`), _tmpl$0$2 = /* @__PURE__ */ template(`<div class=checkpoint-timeline>`), _tmpl$1$2 = /* @__PURE__ */ template(`<section class="agent-panel checkpoint-panel"><div class=agent-panel-header><div><div class=agent-panel-title>Checkpoints</div><div class=agent-panel-subtitle></div></div></div><div class=agent-panel-body><div class=agent-checkpoint-row><input class=agent-input placeholder="Checkpoint name"><button class=agent-primary-button type=button>Save checkpoint</button></div><div class=agent-section-title>Recent checkpoints`), _tmpl$10$2 = /* @__PURE__ */ template(`<div class="kit-upsell premium-chat-banner"><p class=kit-upsell-title>Vessel Premium</p><p class="kit-upsell-body premium-chat-banner-body">Give the built-in agent a bigger toolbox and longer runway: screenshots, saved sessions, workflow tracking, table extraction, and up to 1,000 tool calls per turn.</p><div class="premium-inline-actions premium-chat-banner-actions"><button class="agent-primary-button premium-inline-primary"type=button>Start 7-day free trial — $5.99/mo after</button><button class="agent-control-button premium-inline-secondary"type=button>See Premium`), _tmpl$11$2 = /* @__PURE__ */ template(`<span>`), _tmpl$12$2 = /* @__PURE__ */ template(`<div><div class=streaming-status><span class=streaming-pulse aria-hidden=true></span><span>Generating`), _tmpl$13$1 = /* @__PURE__ */ template(`<div class="message message-assistant"><div class=message-content>`), _tmpl$14$1 = /* @__PURE__ */ template(`<div class=sidebar-empty><svg class=sidebar-empty-icon width=48 height=48 viewBox="0 0 48 48"aria-hidden=true><line x1=8 y1=8 x2=24 y2=5 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=24 y1=5 x2=40 y2=10 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=8 y1=8 x2=6 y2=24 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=40 y1=10 x2=44 y2=26 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=6 y1=24 x2=10 y2=38 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=44 y1=26 x2=38 y2=40 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=10 y1=38 x2=24 y2=44 stroke=var(--border-visible) stroke-width=1 opacity=0.35></line><line x1=38 y1=40 x2=24 y2=44 stroke=var(--border-visible) stroke-width=1 opacity=0.35></line><line x1=8 y1=8 x2=20 y2=18 stroke=var(--border-visible) stroke-width=1 opacity=0.5></line><line x1=24 y1=5 x2=20 y2=18 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=40 y1=10 x2=32 y2=20 stroke=var(--border-visible) stroke-width=1 opacity=0.5></line><line x1=20 y1=18 x2=32 y2=20 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.3></line><line x1=6 y1=24 x2=18 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=20 y1=18 x2=18 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=32 y1=20 x2=36 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=44 y1=26 x2=36 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=18 y1=30 x2=36 y2=30 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.25></line><line x1=18 y1=30 x2=10 y2=38 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=36 y1=30 x2=38 y2=40 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=18 y1=30 x2=24 y2=44 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.2></line><line x1=36 y1=30 x2=24 y2=44 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.2></line><circle cx=8 cy=8 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.55></circle><circle cx=24 cy=5 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.45></circle><circle cx=40 cy=10 r=3 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.7></circle><circle cx=6 cy=24 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=44 cy=26 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.55></circle><circle cx=10 cy=38 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=38 cy=40 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.45></circle><circle cx=24 cy=44 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=20 cy=18 r=3.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.85></circle><circle cx=32 cy=20 r=4 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.9></circle><circle cx=18 cy=30 r=3 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.75></circle><circle cx=36 cy=30 r=3.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.8></circle></svg><p class=sidebar-empty-title>Your move.</p><p class=sidebar-empty-hint>Configure a provider in Settings (Ctrl+,) then ask anything about the current page or beyond.`), _tmpl$15$1 = /* @__PURE__ */ template(`<button class=chat-action-btn title="Stop generating"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><rect x=2 y=2 width=10 height=10 rx=1.5 fill=currentColor></rect></svg>Stop`), _tmpl$16$1 = /* @__PURE__ */ template(`<button class=chat-action-btn title="Retry last prompt"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><path d="M11.5 7a4.5 4.5 0 1 1-1.3-3.2"stroke=currentColor stroke-width=1.5 stroke-linecap=round></path><path d="M10.5 1v3h-3"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg>Retry`), _tmpl$17$1 = /* @__PURE__ */ template(`<div class=chat-actions>`), _tmpl$18$1 = /* @__PURE__ */ template(`<div class=highlight-nav><button class=highlight-nav-btn type=button title="Previous highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><path d="M8 10L4 6l4-4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button><button class=highlight-nav-label type=button title="Go to current highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><circle cx=6 cy=6 r=3 fill="rgba(196, 160, 90, 0.6)"stroke="rgba(196, 160, 90, 0.9)"stroke-width=1></circle></svg></button><button class=highlight-nav-btn type=button title="Next highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><path d="M4 2l4 4-4 4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round>`), _tmpl$19$1 = /* @__PURE__ */ template(`<button class=chat-queue-clear type=button>Clear queue`), _tmpl$20$1 = /* @__PURE__ */ template(`<div class=chat-queue-list>`), _tmpl$21$1 = /* @__PURE__ */ template(`<div class=chat-queue-status><div class=chat-queue-status-row><span>`), _tmpl$22$1 = /* @__PURE__ */ template(`<div class=sidebar-input-area><textarea class=sidebar-input rows=2></textarea><button class=sidebar-send>`), _tmpl$23$1 = /* @__PURE__ */ template(`<div class=sidebar><div class=sidebar-resize-handle></div><div class=sidebar-header><div class=sidebar-brand><img class=sidebar-logo alt=Vessel><span class=sidebar-brand-text>Vessel Browser</span></div><div class=sidebar-header-actions><button class=sidebar-clear title="Clear chat">Clear</button><button class=sidebar-close title="Close AI chat (Esc)"aria-label="Close AI chat"><svg width=14 height=14 viewBox="0 0 14 14"aria-hidden=true><path d="M3.5 3.5l7 7M10.5 3.5l-7 7"fill=none stroke=currentColor stroke-width=1.4 stroke-linecap=round></path></svg></button></div></div><div class=sidebar-tabs role=tablist><button class=sidebar-tab role=tab>Supervisor</button><button class=sidebar-tab role=tab>Bookmarks</button><button class=sidebar-tab role=tab>Checkpoints</button><button class=sidebar-tab role=tab>Chat</button><button class=sidebar-tab role=tab>Automate</button></div><div class=sidebar-messages><div>`), _tmpl$24$1 = /* @__PURE__ */ template(`<div class=agent-muted>No pending approvals.`), _tmpl$25$1 = /* @__PURE__ */ template(`<div class="agent-card agent-card-approval"><div class=agent-card-approval-stripe aria-hidden=true></div><div class=agent-card-title></div><div class=agent-card-copy></div><div class=agent-card-copy></div><div class=agent-card-actions><button class=agent-primary-button type=button>Approve</button><button class=agent-control-button type=button>Reject`), _tmpl$26$1 = /* @__PURE__ */ template(`<div class=agent-muted>No actions yet.`), _tmpl$27$1 = /* @__PURE__ */ template(`<div class=agent-muted>Recent actions are collapsed to reduce noise.`), _tmpl$28$1 = /* @__PURE__ */ template(`<div class="agent-card-copy success">`), _tmpl$29$1 = /* @__PURE__ */ template(`<div class="agent-card-copy error">`), _tmpl$30$1 = /* @__PURE__ */ template(`<div class=agent-card><div class=agent-action-row><span class=agent-card-title></span><span></span></div><div class=agent-card-copy>`), _tmpl$31$1 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>`), _tmpl$32 = /* @__PURE__ */ template(`<div class=bookmark-folder-summary>`), _tmpl$33 = /* @__PURE__ */ template(`<div class=bookmark-folder-actions><button class=bookmark-ghost-button type=button>Rename</button><button class="bookmark-ghost-button danger"type=button>Delete`), _tmpl$34 = /* @__PURE__ */ template(`<button class=bookmark-ghost-button type=button>Keep bookmarks`), _tmpl$35 = /* @__PURE__ */ template(`<div class=bookmark-folder-delete-confirm><p class=bookmark-delete-prompt>Delete "<!>"?</p><div class=bookmark-delete-options><button class="bookmark-ghost-button danger"type=button></button><button class=bookmark-ghost-button type=button>Cancel`), _tmpl$36 = /* @__PURE__ */ template(`<div class=bookmark-folder-edit><div class=bookmark-folder-form-fields><input class=bookmark-input><input class=bookmark-input placeholder="Optional one-line summary"></div><button class=bookmark-secondary-button type=button>Save</button><button class=bookmark-ghost-button type=button>Cancel`), _tmpl$37 = /* @__PURE__ */ template(`<div class=bookmark-items>`), _tmpl$38 = /* @__PURE__ */ template(`<div class=bookmark-folder-section><div class="bookmark-folder-header clickable"role=button tabindex=0><div class=bookmark-folder-overview><span class=bookmark-folder-chevron aria-hidden=true>▸</span><div><div class=bookmark-folder-name></div><div class=bookmark-folder-meta> saved`), _tmpl$39 = /* @__PURE__ */ template(`<div class=bookmark-folder-collapsed-hint>Click to view saved links.`), _tmpl$40 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>No bookmarks in this folder yet.`), _tmpl$41 = /* @__PURE__ */ template(`<div class=bookmark-item-note>`), _tmpl$42 = /* @__PURE__ */ template(`<div class=bookmark-item><button class=bookmark-item-link type=button><span class=bookmark-item-title></span><span class=bookmark-item-url></span></button><div class=bookmark-item-footer><span class=bookmark-item-time></span><button class="bookmark-ghost-button danger"type=button>Remove`), _tmpl$43 = /* @__PURE__ */ template(`<div class=agent-muted>No checkpoints yet.`), _tmpl$44 = /* @__PURE__ */ template(`<span class=checkpoint-timeline-line>`), _tmpl$45 = /* @__PURE__ */ template(`<div class=checkpoint-timeline-item><div class=checkpoint-timeline-rail><span class=checkpoint-timeline-dot></span></div><div class=checkpoint-timeline-content><div class=checkpoint-timeline-name></div><div class=checkpoint-timeline-time></div><button class=agent-control-button type=button>Restore`), _tmpl$46 = /* @__PURE__ */ template(`<div>`), _tmpl$47 = /* @__PURE__ */ template(`<div class=thinking-state><div class=thinking-orb aria-hidden=true><span></span><span></span><span></span></div><div class=thinking-copy><div class=thinking-title>Thinking`), _tmpl$48 = /* @__PURE__ */ template(`<div class=chat-approval-detail>`), _tmpl$49 = /* @__PURE__ */ template(`<div class=chat-approval><div class=chat-approval-icon aria-hidden=true><svg width=16 height=16 viewBox="0 0 16 16"fill=none><path d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM7.25 4.75a.75.75 0 011.5 0v3.5a.75.75 0 01-1.5 0v-3.5zM8 11.5a.75.75 0 110-1.5.75.75 0 010 1.5z"fill=currentColor></path></svg></div><div class=chat-approval-body><div class=chat-approval-title>Approval needed: <strong></strong></div><div class=chat-approval-detail></div><div class=chat-approval-actions><button class="chat-approval-btn chat-approval-approve"type=button>Approve</button><button class="chat-approval-btn chat-approval-reject"type=button>Reject`), _tmpl$50 = /* @__PURE__ */ template(`<div class=chat-queue-item><span class=chat-queue-text></span><button class=chat-queue-remove type=button>×`);
5359
5365
  const UNSORTED_FOLDER = {
5360
5366
  id: "unsorted",
5361
5367
  name: "Unsorted",
@@ -5380,7 +5386,7 @@ function getPremiumPromptKind(content) {
5380
5386
  }
5381
5387
  const PremiumPromptCard = (props) => {
5382
5388
  const title = props.kind === "premium_gate" ? "This workflow needs Premium" : "Need a longer autonomous run?";
5383
- const body = props.kind === "premium_gate" ? "Unlock screenshots, saved sessions, workflow tracking, table extraction, and the credential vault with a 5-day free trial." : "Free chats pause after 50 tool calls in a turn. Vessel Premium raises the ceiling so the agent can finish longer workflows without stopping.";
5389
+ const body = props.kind === "premium_gate" ? "Unlock screenshots, saved sessions, workflow tracking, table extraction, and the credential vault with a 7-day free trial." : "Free chats pause after 50 tool calls in a turn. Vessel Premium raises the ceiling so the agent can finish longer workflows without stopping.";
5384
5390
  return (() => {
5385
5391
  var _el$2 = _tmpl$2$4(), _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.nextSibling, _el$6 = _el$5.nextSibling, _el$7 = _el$6.firstChild, _el$8 = _el$7.nextSibling;
5386
5392
  insert(_el$4, title);
@@ -5613,6 +5619,7 @@ ${contextBlock}` : contextBlock);
5613
5619
  const [editingFolderId, setEditingFolderId] = createSignal(null);
5614
5620
  const [editingFolderName, setEditingFolderName] = createSignal("");
5615
5621
  const [editingFolderSummary, setEditingFolderSummary] = createSignal("");
5622
+ const [deletingFolderId, setDeletingFolderId] = createSignal(null);
5616
5623
  const [expandedFolderIds, setExpandedFolderIds] = createSignal([UNSORTED_FOLDER.id]);
5617
5624
  const [actionsExpanded, setActionsExpanded] = createSignal(false);
5618
5625
  const [checkpointsExpanded, setCheckpointsExpanded] = createSignal(false);
@@ -5712,24 +5719,52 @@ ${contextBlock}` : contextBlock);
5712
5719
  setIsDragging(true);
5713
5720
  document.body.style.cursor = "col-resize";
5714
5721
  document.body.style.userSelect = "none";
5715
- window.vessel.ui.startSidebarResize();
5722
+ void window.vessel.ui.startSidebarResize().catch(() => {
5723
+ });
5716
5724
  const startX = e.screenX;
5717
5725
  const startWidth = sidebarWidth2();
5726
+ let finished = false;
5727
+ const clearPointerTracking = () => {
5728
+ window.removeEventListener("pointermove", onPointerMove);
5729
+ window.removeEventListener("pointerup", onPointerUp);
5730
+ window.removeEventListener("pointercancel", onPointerUp);
5731
+ window.removeEventListener("blur", onWindowBlur);
5732
+ document.removeEventListener("visibilitychange", onVisibilityChange);
5733
+ target.removeEventListener("lostpointercapture", onPointerUp);
5734
+ if (target.hasPointerCapture?.(e.pointerId)) {
5735
+ target.releasePointerCapture(e.pointerId);
5736
+ }
5737
+ };
5718
5738
  const onPointerMove = (ev) => {
5719
5739
  const delta = startX - ev.screenX;
5720
5740
  resizeSidebar(startWidth + delta);
5721
5741
  };
5722
- const onPointerUp = () => {
5742
+ const finishResize = () => {
5743
+ if (finished) return;
5744
+ finished = true;
5723
5745
  setIsDragging(false);
5724
- commitResize();
5725
- target.removeEventListener("pointermove", onPointerMove);
5726
- target.removeEventListener("pointerup", onPointerUp);
5727
- target.removeEventListener("lostpointercapture", onPointerUp);
5746
+ clearPointerTracking();
5728
5747
  document.body.style.cursor = "";
5729
5748
  document.body.style.userSelect = "";
5749
+ void commitResize().catch(() => {
5750
+ });
5751
+ };
5752
+ const onPointerUp = () => {
5753
+ finishResize();
5730
5754
  };
5731
- target.addEventListener("pointermove", onPointerMove);
5732
- target.addEventListener("pointerup", onPointerUp);
5755
+ const onWindowBlur = () => {
5756
+ finishResize();
5757
+ };
5758
+ const onVisibilityChange = () => {
5759
+ if (document.hidden) {
5760
+ finishResize();
5761
+ }
5762
+ };
5763
+ window.addEventListener("pointermove", onPointerMove);
5764
+ window.addEventListener("pointerup", onPointerUp);
5765
+ window.addEventListener("pointercancel", onPointerUp);
5766
+ window.addEventListener("blur", onWindowBlur);
5767
+ document.addEventListener("visibilitychange", onVisibilityChange);
5733
5768
  target.addEventListener("lostpointercapture", onPointerUp);
5734
5769
  };
5735
5770
  const formatBookmarkDate = (savedAt) => new Date(savedAt).toLocaleDateString(void 0, {
@@ -5763,11 +5798,10 @@ ${contextBlock}` : contextBlock);
5763
5798
  setEditingFolderName("");
5764
5799
  setEditingFolderSummary("");
5765
5800
  };
5766
- const handleRemoveFolder = async (folderId) => {
5767
- const confirmed = window.confirm("Delete this folder? Its bookmarks will move to Unsorted.");
5768
- if (!confirmed) return;
5769
- const removed = await removeFolder(folderId);
5801
+ const handleRemoveFolder = async (folderId, deleteContents) => {
5802
+ const removed = await removeFolder(folderId, deleteContents);
5770
5803
  if (!removed) return;
5804
+ setDeletingFolderId(null);
5771
5805
  if (selectedFolderId() === folderId) {
5772
5806
  setSelectedFolderId(UNSORTED_FOLDER.id);
5773
5807
  }
@@ -6001,7 +6035,7 @@ ${contextBlock}` : contextBlock);
6001
6035
  return filteredGroupedBookmarks();
6002
6036
  },
6003
6037
  children: (folder) => (() => {
6004
- var _el$122 = _tmpl$36(), _el$123 = _el$122.firstChild, _el$124 = _el$123.firstChild, _el$125 = _el$124.firstChild, _el$126 = _el$125.nextSibling, _el$127 = _el$126.firstChild, _el$128 = _el$127.nextSibling, _el$129 = _el$128.firstChild;
6038
+ var _el$122 = _tmpl$38(), _el$123 = _el$122.firstChild, _el$124 = _el$123.firstChild, _el$125 = _el$124.firstChild, _el$126 = _el$125.nextSibling, _el$127 = _el$126.firstChild, _el$128 = _el$127.nextSibling, _el$129 = _el$128.firstChild;
6005
6039
  _el$123.$$keydown = (e) => {
6006
6040
  if (e.key === "Enter" || e.key === " ") {
6007
6041
  e.preventDefault();
@@ -6035,29 +6069,58 @@ ${contextBlock}` : contextBlock);
6035
6069
  };
6036
6070
  _el$133.$$click = (e) => {
6037
6071
  e.stopPropagation();
6038
- void handleRemoveFolder(folder.id);
6072
+ setDeletingFolderId(folder.id);
6039
6073
  };
6040
6074
  return _el$131;
6041
6075
  }
6042
6076
  }), null);
6077
+ insert(_el$122, createComponent(Show, {
6078
+ get when() {
6079
+ return deletingFolderId() === folder.id;
6080
+ },
6081
+ get children() {
6082
+ var _el$134 = _tmpl$35(), _el$135 = _el$134.firstChild, _el$136 = _el$135.firstChild, _el$138 = _el$136.nextSibling;
6083
+ _el$138.nextSibling;
6084
+ var _el$139 = _el$135.nextSibling, _el$141 = _el$139.firstChild, _el$142 = _el$141.nextSibling;
6085
+ insert(_el$135, () => folder.name, _el$138);
6086
+ insert(_el$135, (() => {
6087
+ var _c$6 = memo(() => folder.items.length > 0);
6088
+ return () => _c$6() ? ` This folder has ${folder.items.length} bookmark${folder.items.length === 1 ? "" : "s"}.` : "";
6089
+ })(), null);
6090
+ insert(_el$139, createComponent(Show, {
6091
+ get when() {
6092
+ return folder.items.length > 0;
6093
+ },
6094
+ get children() {
6095
+ var _el$140 = _tmpl$34();
6096
+ _el$140.$$click = () => void handleRemoveFolder(folder.id, false);
6097
+ return _el$140;
6098
+ }
6099
+ }), _el$141);
6100
+ _el$141.$$click = () => void handleRemoveFolder(folder.id, true);
6101
+ insert(_el$141, () => folder.items.length > 0 ? "Delete all" : "Delete folder");
6102
+ _el$142.$$click = () => setDeletingFolderId(null);
6103
+ return _el$134;
6104
+ }
6105
+ }), null);
6043
6106
  insert(_el$122, createComponent(Show, {
6044
6107
  get when() {
6045
6108
  return editingFolderId() === folder.id;
6046
6109
  },
6047
6110
  get children() {
6048
- var _el$134 = _tmpl$34(), _el$135 = _el$134.firstChild, _el$136 = _el$135.firstChild, _el$137 = _el$136.nextSibling, _el$138 = _el$135.nextSibling, _el$139 = _el$138.nextSibling;
6049
- _el$136.$$input = (e) => setEditingFolderName(e.currentTarget.value);
6050
- _el$137.$$input = (e) => setEditingFolderSummary(e.currentTarget.value);
6051
- _el$138.$$click = () => void handleRenameFolder(folder.id);
6052
- _el$139.$$click = () => {
6111
+ var _el$143 = _tmpl$36(), _el$144 = _el$143.firstChild, _el$145 = _el$144.firstChild, _el$146 = _el$145.nextSibling, _el$147 = _el$144.nextSibling, _el$148 = _el$147.nextSibling;
6112
+ _el$145.$$input = (e) => setEditingFolderName(e.currentTarget.value);
6113
+ _el$146.$$input = (e) => setEditingFolderSummary(e.currentTarget.value);
6114
+ _el$147.$$click = () => void handleRenameFolder(folder.id);
6115
+ _el$148.$$click = () => {
6053
6116
  setEditingFolderId(null);
6054
6117
  setEditingFolderName("");
6055
6118
  setEditingFolderSummary("");
6056
6119
  };
6057
- createRenderEffect(() => _el$138.disabled = !editingFolderName().trim());
6058
- createRenderEffect(() => _el$136.value = editingFolderName());
6059
- createRenderEffect(() => _el$137.value = editingFolderSummary());
6060
- return _el$134;
6120
+ createRenderEffect(() => _el$147.disabled = !editingFolderName().trim());
6121
+ createRenderEffect(() => _el$145.value = editingFolderName());
6122
+ createRenderEffect(() => _el$146.value = editingFolderSummary());
6123
+ return _el$143;
6061
6124
  }
6062
6125
  }), null);
6063
6126
  insert(_el$122, createComponent(Show, {
@@ -6065,7 +6128,7 @@ ${contextBlock}` : contextBlock);
6065
6128
  return isFolderExpanded(folder.id);
6066
6129
  },
6067
6130
  get fallback() {
6068
- return _tmpl$37();
6131
+ return _tmpl$39();
6069
6132
  },
6070
6133
  get children() {
6071
6134
  return createComponent(Show, {
@@ -6073,36 +6136,36 @@ ${contextBlock}` : contextBlock);
6073
6136
  return folder.items.length > 0;
6074
6137
  },
6075
6138
  get fallback() {
6076
- return _tmpl$38();
6139
+ return _tmpl$40();
6077
6140
  },
6078
6141
  get children() {
6079
- var _el$140 = _tmpl$35();
6080
- insert(_el$140, createComponent(For, {
6142
+ var _el$149 = _tmpl$37();
6143
+ insert(_el$149, createComponent(For, {
6081
6144
  get each() {
6082
6145
  return folder.items;
6083
6146
  },
6084
6147
  children: (bookmark) => (() => {
6085
- var _el$143 = _tmpl$40(), _el$144 = _el$143.firstChild, _el$145 = _el$144.firstChild, _el$146 = _el$145.nextSibling, _el$148 = _el$144.nextSibling, _el$149 = _el$148.firstChild, _el$150 = _el$149.nextSibling;
6086
- _el$144.$$click = () => void createTab(bookmark.url);
6087
- insert(_el$145, () => bookmark.title || bookmark.url);
6088
- insert(_el$146, () => bookmark.url);
6089
- insert(_el$143, createComponent(Show, {
6148
+ var _el$152 = _tmpl$42(), _el$153 = _el$152.firstChild, _el$154 = _el$153.firstChild, _el$155 = _el$154.nextSibling, _el$157 = _el$153.nextSibling, _el$158 = _el$157.firstChild, _el$159 = _el$158.nextSibling;
6149
+ _el$153.$$click = () => void createTab(bookmark.url);
6150
+ insert(_el$154, () => bookmark.title || bookmark.url);
6151
+ insert(_el$155, () => bookmark.url);
6152
+ insert(_el$152, createComponent(Show, {
6090
6153
  get when() {
6091
6154
  return bookmark.note;
6092
6155
  },
6093
6156
  get children() {
6094
- var _el$147 = _tmpl$39();
6095
- insert(_el$147, () => bookmark.note);
6096
- return _el$147;
6157
+ var _el$156 = _tmpl$41();
6158
+ insert(_el$156, () => bookmark.note);
6159
+ return _el$156;
6097
6160
  }
6098
- }), _el$148);
6099
- insert(_el$149, () => formatBookmarkDate(bookmark.savedAt));
6100
- _el$150.$$click = () => void removeBookmark(bookmark.id);
6101
- createRenderEffect(() => setAttribute(_el$143, "data-bookmark-id", bookmark.id));
6102
- return _el$143;
6161
+ }), _el$157);
6162
+ insert(_el$158, () => formatBookmarkDate(bookmark.savedAt));
6163
+ _el$159.$$click = () => void removeBookmark(bookmark.id);
6164
+ createRenderEffect(() => setAttribute(_el$152, "data-bookmark-id", bookmark.id));
6165
+ return _el$152;
6103
6166
  })()
6104
6167
  }));
6105
- return _el$140;
6168
+ return _el$149;
6106
6169
  }
6107
6170
  });
6108
6171
  }
@@ -6150,7 +6213,7 @@ ${contextBlock}` : contextBlock);
6150
6213
  return recentCheckpoints().length > 0;
6151
6214
  },
6152
6215
  get fallback() {
6153
- return _tmpl$41();
6216
+ return _tmpl$43();
6154
6217
  },
6155
6218
  get children() {
6156
6219
  var _el$71 = _tmpl$0$2();
@@ -6159,20 +6222,20 @@ ${contextBlock}` : contextBlock);
6159
6222
  return recentCheckpoints();
6160
6223
  },
6161
6224
  children: (checkpoint, i) => (() => {
6162
- var _el$152 = _tmpl$43(), _el$153 = _el$152.firstChild, _el$154 = _el$153.firstChild, _el$156 = _el$153.nextSibling, _el$157 = _el$156.firstChild, _el$158 = _el$157.nextSibling, _el$159 = _el$158.nextSibling;
6163
- insert(_el$153, createComponent(Show, {
6225
+ var _el$161 = _tmpl$45(), _el$162 = _el$161.firstChild, _el$163 = _el$162.firstChild, _el$165 = _el$162.nextSibling, _el$166 = _el$165.firstChild, _el$167 = _el$166.nextSibling, _el$168 = _el$167.nextSibling;
6226
+ insert(_el$162, createComponent(Show, {
6164
6227
  get when() {
6165
6228
  return i() < recentCheckpoints().length - 1;
6166
6229
  },
6167
6230
  get children() {
6168
- return _tmpl$42();
6231
+ return _tmpl$44();
6169
6232
  }
6170
6233
  }), null);
6171
- insert(_el$157, () => checkpoint.name);
6172
- insert(_el$158, () => new Date(checkpoint.createdAt).toLocaleString());
6173
- _el$159.$$click = () => void restoreCheckpoint(checkpoint.id);
6174
- createRenderEffect(() => _el$154.classList.toggle("latest", !!(i() === 0)));
6175
- return _el$152;
6234
+ insert(_el$166, () => checkpoint.name);
6235
+ insert(_el$167, () => new Date(checkpoint.createdAt).toLocaleString());
6236
+ _el$168.$$click = () => void restoreCheckpoint(checkpoint.id);
6237
+ createRenderEffect(() => _el$163.classList.toggle("latest", !!(i() === 0)));
6238
+ return _el$161;
6176
6239
  })()
6177
6240
  }));
6178
6241
  return _el$71;
@@ -6212,13 +6275,13 @@ ${contextBlock}` : contextBlock);
6212
6275
  return messages2();
6213
6276
  },
6214
6277
  children: (msg) => (() => {
6215
- var _el$160 = _tmpl$44();
6216
- insert(_el$160, createComponent(MarkdownMessage, {
6278
+ var _el$169 = _tmpl$46();
6279
+ insert(_el$169, createComponent(MarkdownMessage, {
6217
6280
  get content() {
6218
6281
  return msg.content;
6219
6282
  }
6220
6283
  }), null);
6221
- insert(_el$160, createComponent(Show, {
6284
+ insert(_el$169, createComponent(Show, {
6222
6285
  get when() {
6223
6286
  return memo(() => msg.role === "assistant")() ? getPremiumPromptKind(msg.content) : null;
6224
6287
  },
@@ -6231,8 +6294,8 @@ ${contextBlock}` : contextBlock);
6231
6294
  onOpenSettings: openPremiumDetails
6232
6295
  })
6233
6296
  }), null);
6234
- createRenderEffect(() => className(_el$160, `message message-${msg.role}`));
6235
- return _el$160;
6297
+ createRenderEffect(() => className(_el$169, `message message-${msg.role}`));
6298
+ return _el$169;
6236
6299
  })()
6237
6300
  }), createComponent(Show, {
6238
6301
  get when() {
@@ -6245,7 +6308,7 @@ ${contextBlock}` : contextBlock);
6245
6308
  return hasFirstChunk2();
6246
6309
  },
6247
6310
  get fallback() {
6248
- return _tmpl$45();
6311
+ return _tmpl$47();
6249
6312
  },
6250
6313
  get children() {
6251
6314
  var _el$80 = _tmpl$12$2(), _el$81 = _el$80.firstChild, _el$82 = _el$81.firstChild;
@@ -6293,22 +6356,22 @@ ${contextBlock}` : contextBlock);
6293
6356
  return runtimeState2().supervisor.pendingApprovals;
6294
6357
  },
6295
6358
  children: (approval) => (() => {
6296
- var _el$162 = _tmpl$47(), _el$163 = _el$162.firstChild, _el$164 = _el$163.nextSibling, _el$165 = _el$164.firstChild, _el$166 = _el$165.firstChild, _el$167 = _el$166.nextSibling, _el$169 = _el$165.nextSibling, _el$170 = _el$169.nextSibling, _el$171 = _el$170.firstChild, _el$172 = _el$171.nextSibling;
6297
- insert(_el$167, () => approval.name);
6298
- insert(_el$164, createComponent(Show, {
6359
+ var _el$171 = _tmpl$49(), _el$172 = _el$171.firstChild, _el$173 = _el$172.nextSibling, _el$174 = _el$173.firstChild, _el$175 = _el$174.firstChild, _el$176 = _el$175.nextSibling, _el$178 = _el$174.nextSibling, _el$179 = _el$178.nextSibling, _el$180 = _el$179.firstChild, _el$181 = _el$180.nextSibling;
6360
+ insert(_el$176, () => approval.name);
6361
+ insert(_el$173, createComponent(Show, {
6299
6362
  get when() {
6300
6363
  return approval.argsSummary;
6301
6364
  },
6302
6365
  get children() {
6303
- var _el$168 = _tmpl$46();
6304
- insert(_el$168, () => approval.argsSummary);
6305
- return _el$168;
6366
+ var _el$177 = _tmpl$48();
6367
+ insert(_el$177, () => approval.argsSummary);
6368
+ return _el$177;
6306
6369
  }
6307
- }), _el$169);
6308
- insert(_el$169, () => approval.reason);
6309
- _el$171.$$click = () => void resolveApproval(approval.id, true);
6310
- _el$172.$$click = () => void resolveApproval(approval.id, false);
6311
- return _el$162;
6370
+ }), _el$178);
6371
+ insert(_el$178, () => approval.reason);
6372
+ _el$180.$$click = () => void resolveApproval(approval.id, true);
6373
+ _el$181.$$click = () => void resolveApproval(approval.id, false);
6374
+ return _el$171;
6312
6375
  })()
6313
6376
  });
6314
6377
  }
@@ -6411,12 +6474,12 @@ ${contextBlock}` : contextBlock);
6411
6474
  return pendingQueries2();
6412
6475
  },
6413
6476
  children: (pendingPrompt, index) => (() => {
6414
- var _el$173 = _tmpl$48(), _el$174 = _el$173.firstChild, _el$175 = _el$174.nextSibling;
6415
- setAttribute(_el$174, "title", pendingPrompt);
6416
- insert(_el$174, pendingPrompt);
6417
- _el$175.$$click = () => removePendingQuery(index());
6418
- createRenderEffect(() => setAttribute(_el$175, "aria-label", `Remove queued prompt ${index() + 1}`));
6419
- return _el$173;
6477
+ var _el$182 = _tmpl$50(), _el$183 = _el$182.firstChild, _el$184 = _el$183.nextSibling;
6478
+ setAttribute(_el$183, "title", pendingPrompt);
6479
+ insert(_el$183, pendingPrompt);
6480
+ _el$184.$$click = () => removePendingQuery(index());
6481
+ createRenderEffect(() => setAttribute(_el$184, "aria-label", `Remove queued prompt ${index() + 1}`));
6482
+ return _el$182;
6420
6483
  })()
6421
6484
  }));
6422
6485
  return _el$99;
@@ -6914,7 +6977,7 @@ const DevToolsPanel = () => {
6914
6977
  })();
6915
6978
  };
6916
6979
  delegateEvents(["click", "input"]);
6917
- var _tmpl$$2 = /* @__PURE__ */ template(`<div class=welcome-banner-actions><button class="premium-btn premium-btn-upgrade">Try Premium free for 5 days</button><span class=welcome-banner-note>Best for screenshots, saved sessions, credential vault, and longer autonomous runs.`), _tmpl$2$2 = /* @__PURE__ */ template(`<div class=welcome-banner><div class=welcome-banner-header><span class=welcome-banner-title>Welcome to Vessel</span><button class=welcome-banner-dismiss>&times;</button></div><p class=welcome-banner-text>Get started in three steps:</p><ol class=welcome-banner-steps><li><strong>Configure a chat provider</strong> — scroll to Chat Assistant below and add an API key</li><li><strong>Connect your agent harness</strong> — point it at the MCP endpoint shown below</li><li><strong>Learn the shortcuts</strong> — press <kbd>?</kbd> anytime for a quick reference`), _tmpl$3$1 = /* @__PURE__ */ template(`<div class="settings-callout settings-premium-callout"><div class=settings-callout-title>Start Vessel Premium with a 5-day free trial</div><p class=settings-callout-copy>Unlock screenshots, saved sessions, workflow tracking, table extraction, the credential vault, and longer autonomous runs without leaving the app.</p><div class=settings-premium-callout-actions><button class="premium-btn premium-btn-upgrade">Start free trial</button><button class="premium-btn premium-btn-activate">See activation steps`), _tmpl$4$1 = /* @__PURE__ */ template(`<input id=max-tool-iterations class=settings-input type=number min=10 max=1000 placeholder=200>`), _tmpl$5$1 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-provider>Provider</label><select id=chat-provider class="settings-input settings-select">`), _tmpl$6$1 = /* @__PURE__ */ template(`<span class=settings-label-optional> (optional)`), _tmpl$7 = /* @__PURE__ */ template(`<p class=settings-hint>If your endpoint requires authentication, enter the API key or bearer token here.`), _tmpl$8 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-api-key>API Key</label><input id=chat-api-key class=settings-input type=password>`), _tmpl$9 = /* @__PURE__ */ template(`<select id=chat-model class="settings-input settings-select"style=flex:1>`), _tmpl$0 = /* @__PURE__ */ template(`<p class=settings-hint style=color:var(--error)>Could not fetch models — check your API key and connection.`), _tmpl$1 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-model>Model</label><div style=display:flex;gap:6px;align-items:center><button type=button class=settings-refresh-btn title="Refresh model list">↺`), _tmpl$10 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-base-url>Base URL</label><input id=chat-base-url class=settings-input>`), _tmpl$11 = /* @__PURE__ */ template(`<div class=premium-section><div class=premium-active-badge>Premium Active</div><p class=premium-detail></p><div class=premium-actions-row><button class="premium-btn premium-btn-manage">Manage Subscription</button><button class="premium-btn premium-btn-reset">Sign Out`), _tmpl$12 = /* @__PURE__ */ template(`<span class=vault-premium-badge>Premium`), _tmpl$13 = /* @__PURE__ */ template(`<p class=settings-hint style=margin-bottom:10px>Store credentials for agent-driven logins. Credentials are encrypted at rest and never sent to AI providers — they are filled directly into login forms with your consent.`), _tmpl$14 = /* @__PURE__ */ template(`<div class=vault-entries>`), _tmpl$15 = /* @__PURE__ */ template(`<button class=vault-add-btn>+ Add Credential`), _tmpl$16 = /* @__PURE__ */ template(`<div class=vault-add-form><input class=settings-input placeholder="Label (e.g. Work GitHub)"><input class=settings-input placeholder="Domain pattern (e.g. github.com, *.aws.amazon.com)"><input class=settings-input placeholder="Username / email"><input class=settings-input type=password placeholder=Password><input class=settings-input placeholder="TOTP secret (optional, base32)"><input class=settings-input placeholder="Notes (optional)"><div class=vault-add-actions><button class="premium-btn premium-btn-activate">Save Credential</button><button class="premium-btn premium-btn-reset">Cancel`), _tmpl$17 = /* @__PURE__ */ template(`<div class=command-bar-overlay><div class=settings-panel><h2 class=settings-title>Runtime Settings</h2><div class=settings-callout><div class=settings-callout-title>External Agent Control</div><p class=settings-callout-copy>Vessel is configured to run under an external harness such as Hermes Agent or OpenClaw. Provider and model selection are not configured inside Vessel.</p></div><div class=settings-field><label class=settings-label for=default-homepage>Homepage</label><input id=default-homepage class=settings-input placeholder=https://start.duckduckgo.com><p class=settings-hint>The page that opens when you create a new tab or launch Vessel without restoring a previous session.</p></div><div class=settings-field><label class=settings-label for=mcp-port>MCP Port</label><input id=mcp-port class=settings-input placeholder=3100><p class=settings-hint>External harnesses connect to Vessel at <code>http://127.0.0.1:&lt;port&gt;/mcp</code>. Changing this value restarts the MCP server immediately.</p></div><div class=settings-field><label class=settings-label for=max-tool-iterations>Max Tool Iterations</label><p class=settings-hint></p></div><div class=settings-field><label class=settings-label for=obsidian-vault-path>Obsidian Vault Path</label><input id=obsidian-vault-path class=settings-input placeholder=/home/you/Documents/MyVault><p class=settings-hint>Optional. When set, Vessel memory tools can write markdown notes into this vault for research breadcrumbs and summaries.</p></div><div class=settings-field><label class=settings-label for=agent-transcript-mode>Agent Transcript Monitor</label><select id=agent-transcript-mode class="settings-input settings-select"><option value=off>Off</option><option value=summary>Summary HUD</option><option value=full>Full transcript</option></select><p class=settings-hint>Controls the in-browser transcript monitor when an external harness publishes reasoning or status updates into Vessel via the<code>vessel_publish_transcript</code> MCP tool. Summary HUD shows a compact 2-line status surface; Full transcript shows the recent entry list.</p></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Restore last browser session on launch</span></label></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Start bookmarks fresh on launch</span></label><p class=settings-hint>Off by default. When enabled, bookmark folders and saved pages are cleared each time Vessel starts.</p></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Enable Chat Assistant</span></label><p class=settings-hint>Adds a Chat tab to the sidebar for conversing with an AI provider of your choice.</p></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-label>Vessel Premium</label></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-label>Agent Credential Vault</label></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Anonymous Usage Analytics</span></label><p class=settings-hint>Help improve Vessel by sending anonymous usage data (tool popularity, session duration, provider type). No URLs, page content, queries, or personal data is ever collected.</p></div><div class=settings-actions><button class=settings-save>Save</button><button class=settings-close>Close`), _tmpl$18 = /* @__PURE__ */ template(`<style>
6980
+ var _tmpl$$2 = /* @__PURE__ */ template(`<div class=welcome-banner-actions><button class="premium-btn premium-btn-upgrade">Try Premium free for 7 days — $5.99/mo after</button><span class=welcome-banner-note>Best for screenshots, saved sessions, credential vault, and longer autonomous runs.`), _tmpl$2$2 = /* @__PURE__ */ template(`<div class=welcome-banner><div class=welcome-banner-header><span class=welcome-banner-title>Welcome to Vessel</span><button class=welcome-banner-dismiss>&times;</button></div><p class=welcome-banner-text>Get started in three steps:</p><ol class=welcome-banner-steps><li><strong>Configure a chat provider</strong> — scroll to Chat Assistant below and add an API key</li><li><strong>Connect your agent harness</strong> — point it at the MCP endpoint shown below</li><li><strong>Learn the shortcuts</strong> — press <kbd>?</kbd> anytime for a quick reference`), _tmpl$3$1 = /* @__PURE__ */ template(`<div class="settings-callout settings-premium-callout"><div class=settings-callout-title>Start Vessel Premium with a 7-day free trial</div><p class=settings-callout-copy>Unlock screenshots, saved sessions, workflow tracking, table extraction, the credential vault, and longer autonomous runs without leaving the app.</p><div class=settings-premium-callout-actions><button class="premium-btn premium-btn-upgrade">Start 7-day free trial — $5.99/mo after</button><button class="premium-btn premium-btn-activate">See activation steps`), _tmpl$4$1 = /* @__PURE__ */ template(`<input id=max-tool-iterations class=settings-input type=number min=10 max=1000 placeholder=200>`), _tmpl$5$1 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-provider>Provider</label><select id=chat-provider class="settings-input settings-select">`), _tmpl$6$1 = /* @__PURE__ */ template(`<span class=settings-label-optional> (optional)`), _tmpl$7 = /* @__PURE__ */ template(`<p class=settings-hint>If your endpoint requires authentication, enter the API key or bearer token here.`), _tmpl$8 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-api-key>API Key</label><input id=chat-api-key class=settings-input type=password>`), _tmpl$9 = /* @__PURE__ */ template(`<select id=chat-model class="settings-input settings-select"style=flex:1>`), _tmpl$0 = /* @__PURE__ */ template(`<p class=settings-hint style=color:var(--error)>Could not fetch models — check your API key and connection.`), _tmpl$1 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-model>Model</label><div style=display:flex;gap:6px;align-items:center><button type=button class=settings-refresh-btn title="Refresh model list">↺`), _tmpl$10 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-base-url>Base URL</label><input id=chat-base-url class=settings-input>`), _tmpl$11 = /* @__PURE__ */ template(`<div class=premium-section><div class=premium-active-badge>Premium Active</div><p class=premium-detail></p><div class=premium-actions-row><button class="premium-btn premium-btn-manage">Manage Subscription</button><button class="premium-btn premium-btn-reset">Sign Out`), _tmpl$12 = /* @__PURE__ */ template(`<span class=vault-premium-badge>Premium`), _tmpl$13 = /* @__PURE__ */ template(`<p class=settings-hint style=margin-bottom:10px>Store credentials for agent-driven logins. Credentials are encrypted at rest and never sent to AI providers — they are filled directly into login forms with your consent.`), _tmpl$14 = /* @__PURE__ */ template(`<div class=vault-entries>`), _tmpl$15 = /* @__PURE__ */ template(`<button class=vault-add-btn>+ Add Credential`), _tmpl$16 = /* @__PURE__ */ template(`<div class=vault-add-form><input class=settings-input placeholder="Label (e.g. Work GitHub)"><input class=settings-input placeholder="Domain pattern (e.g. github.com, *.aws.amazon.com)"><input class=settings-input placeholder="Username / email"><input class=settings-input type=password placeholder=Password><input class=settings-input placeholder="TOTP secret (optional, base32)"><input class=settings-input placeholder="Notes (optional)"><div class=vault-add-actions><button class="premium-btn premium-btn-activate">Save Credential</button><button class="premium-btn premium-btn-reset">Cancel`), _tmpl$17 = /* @__PURE__ */ template(`<div class=command-bar-overlay><div class=settings-panel><h2 class=settings-title>Runtime Settings</h2><div class=settings-callout><div class=settings-callout-title>External Agent Control</div><p class=settings-callout-copy>Vessel is configured to run under an external harness such as Hermes Agent or OpenClaw. Provider and model selection are not configured inside Vessel.</p></div><div class=settings-field><label class=settings-label for=default-homepage>Homepage</label><input id=default-homepage class=settings-input placeholder=https://start.duckduckgo.com><p class=settings-hint>The page that opens when you create a new tab or launch Vessel without restoring a previous session.</p></div><div class=settings-field><label class=settings-label for=mcp-port>MCP Port</label><input id=mcp-port class=settings-input placeholder=3100><p class=settings-hint>External harnesses connect to Vessel at <code>http://127.0.0.1:&lt;port&gt;/mcp</code>. Changing this value restarts the MCP server immediately.</p></div><div class=settings-field><label class=settings-label for=max-tool-iterations>Max Tool Iterations</label><p class=settings-hint></p></div><div class=settings-field><label class=settings-label for=obsidian-vault-path>Obsidian Vault Path</label><input id=obsidian-vault-path class=settings-input placeholder=/home/you/Documents/MyVault><p class=settings-hint>Optional. When set, Vessel memory tools can write markdown notes into this vault for research breadcrumbs and summaries.</p></div><div class=settings-field><label class=settings-label for=agent-transcript-mode>Agent Transcript Monitor</label><select id=agent-transcript-mode class="settings-input settings-select"><option value=off>Off</option><option value=summary>Summary HUD</option><option value=full>Full transcript</option></select><p class=settings-hint>Controls the in-browser transcript monitor when an external harness publishes reasoning or status updates into Vessel via the<code>vessel_publish_transcript</code> MCP tool. Summary HUD shows a compact 2-line status surface; Full transcript shows the recent entry list.</p></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Restore last browser session on launch</span></label></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Start bookmarks fresh on launch</span></label><p class=settings-hint>Off by default. When enabled, bookmark folders and saved pages are cleared each time Vessel starts.</p></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Enable Chat Assistant</span></label><p class=settings-hint>Adds a Chat tab to the sidebar for conversing with an AI provider of your choice.</p></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-label>Vessel Premium</label></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-label>Agent Credential Vault</label></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Anonymous Usage Analytics</span></label><p class=settings-hint>Help improve Vessel by sending anonymous usage data (tool popularity, session duration, provider type). No URLs, page content, queries, or personal data is ever collected.</p></div><div class=settings-actions><button class=settings-save>Save</button><button class=settings-close>Close`), _tmpl$18 = /* @__PURE__ */ template(`<style>
6918
6981
  .settings-panel {
6919
6982
  width: min(440px, calc(100vw - 32px));
6920
6983
  max-height: calc(100vh - 48px);
@@ -7445,7 +7508,7 @@ var _tmpl$$2 = /* @__PURE__ */ template(`<div class=welcome-banner-actions><butt
7445
7508
  justify-content: flex-end;
7446
7509
  margin-top: 4px;
7447
7510
  }
7448
- `), _tmpl$19 = /* @__PURE__ */ template(`<div class="settings-input settings-input-disabled"title="Upgrade to Vessel Premium for unlimited tool iterations">50`), _tmpl$20 = /* @__PURE__ */ template(`<div class=settings-health-issues>`), _tmpl$21 = /* @__PURE__ */ template(`<div class=settings-health><div class=settings-callout-title>Runtime Health</div><p class=settings-hint>MCP status: <strong></strong> `), _tmpl$22 = /* @__PURE__ */ template(`<p class=settings-hint>Active endpoint: <code>`), _tmpl$23 = /* @__PURE__ */ template(`<div class=settings-health-issue><strong></strong><div>`), _tmpl$24 = /* @__PURE__ */ template(`<div>`), _tmpl$25 = /* @__PURE__ */ template(`<option>`), _tmpl$26 = /* @__PURE__ */ template(`<input id=chat-model class=settings-input style=flex:1>`), _tmpl$27 = /* @__PURE__ */ template(`<button class="premium-btn premium-btn-reset">Clear Saved Email`), _tmpl$28 = /* @__PURE__ */ template(`<div class=premium-section><p class=premium-description>Unlock screenshot/vision analysis, session management, Obsidian integration, workflow tracking, DevTools tools, table extraction, Agent Credential Vault, and unlimited tool iterations.</p><div class=premium-activate-row><input class="settings-input premium-email-input"type=email placeholder="Enter your subscription email"><button class="premium-btn premium-btn-activate"></button></div><button class="premium-btn premium-btn-upgrade">Subscribe to Premium — 5-day free trial`), _tmpl$29 = /* @__PURE__ */ template(`<p class=settings-status>`), _tmpl$30 = /* @__PURE__ */ template(`<p class=settings-hint>Securely store credentials for agent-driven logins. Upgrade to Premium to unlock the Agent Credential Vault.`), _tmpl$31 = /* @__PURE__ */ template(`<div class=vault-entry><div class=vault-entry-info><span class=vault-entry-label></span><span class=vault-entry-detail> &middot; </span></div><button class=vault-entry-remove title="Remove credential">&times;`);
7511
+ `), _tmpl$19 = /* @__PURE__ */ template(`<div class="settings-input settings-input-disabled"title="Upgrade to Vessel Premium for unlimited tool iterations">50`), _tmpl$20 = /* @__PURE__ */ template(`<div class=settings-health-issues>`), _tmpl$21 = /* @__PURE__ */ template(`<div class=settings-health><div class=settings-callout-title>Runtime Health</div><p class=settings-hint>MCP status: <strong></strong> `), _tmpl$22 = /* @__PURE__ */ template(`<p class=settings-hint>Active endpoint: <code>`), _tmpl$23 = /* @__PURE__ */ template(`<div class=settings-health-issue><strong></strong><div>`), _tmpl$24 = /* @__PURE__ */ template(`<div>`), _tmpl$25 = /* @__PURE__ */ template(`<option>`), _tmpl$26 = /* @__PURE__ */ template(`<input id=chat-model class=settings-input style=flex:1>`), _tmpl$27 = /* @__PURE__ */ template(`<button class="premium-btn premium-btn-reset">Clear Saved Email`), _tmpl$28 = /* @__PURE__ */ template(`<div class=premium-section><p class=premium-description>Unlock screenshot/vision analysis, session management, Obsidian integration, workflow tracking, DevTools tools, table extraction, Agent Credential Vault, and unlimited tool iterations.</p><div class=premium-activate-row><input class="settings-input premium-email-input"type=email placeholder="Enter your subscription email"><button class="premium-btn premium-btn-activate"></button></div><button class="premium-btn premium-btn-upgrade">Subscribe to Premium — $5.99/mo after 7-day free trial`), _tmpl$29 = /* @__PURE__ */ template(`<p class=settings-status>`), _tmpl$30 = /* @__PURE__ */ template(`<p class=settings-hint>Securely store credentials for agent-driven logins. Upgrade to Premium to unlock the Agent Credential Vault.`), _tmpl$31 = /* @__PURE__ */ template(`<div class=vault-entry><div class=vault-entry-info><span class=vault-entry-label></span><span class=vault-entry-detail> &middot; </span></div><button class=vault-entry-remove title="Remove credential">&times;`);
7449
7512
  const CHAT_PROVIDERS = [{
7450
7513
  id: "anthropic",
7451
7514
  name: "Anthropic",
@@ -1587,6 +1587,27 @@
1587
1587
  align-items: stretch;
1588
1588
  }
1589
1589
 
1590
+ .bookmark-folder-delete-confirm {
1591
+ padding: 8px 12px;
1592
+ background: rgba(255, 142, 142, 0.04);
1593
+ border: 1px solid rgba(255, 142, 142, 0.12);
1594
+ border-radius: var(--radius-md);
1595
+ margin-top: 4px;
1596
+ }
1597
+
1598
+ .bookmark-delete-prompt {
1599
+ font-size: 12px;
1600
+ color: var(--text-secondary);
1601
+ margin: 0 0 8px;
1602
+ line-height: 1.4;
1603
+ }
1604
+
1605
+ .bookmark-delete-options {
1606
+ display: flex;
1607
+ gap: 6px;
1608
+ flex-wrap: wrap;
1609
+ }
1610
+
1590
1611
  .bookmark-folder-form-fields {
1591
1612
  display: flex;
1592
1613
  flex: 1;
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; font-src 'self' data:;" />
7
7
  <title>Vessel</title>
8
- <script type="module" crossorigin src="./assets/index-D38a5Gkn.js"></script>
9
- <link rel="stylesheet" crossorigin href="./assets/index-DP2yMHwF.css">
8
+ <script type="module" crossorigin src="./assets/index-BnUB1gZc.js"></script>
9
+ <link rel="stylesheet" crossorigin href="./assets/index-Ct7z7yP_.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@quanta-intellect/vessel-browser",
3
3
  "mcpName": "io.github.unmodeled-tyler/vessel-browser",
4
- "version": "0.1.28",
4
+ "version": "0.1.29",
5
5
  "description": "AI-native web browser for Linux — persistent browser runtime for autonomous agents with human supervision",
6
6
  "main": "./out/main/index.js",
7
7
  "bin": {