@quanta-intellect/vessel-browser 0.1.80 → 0.1.83

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
@@ -1,5 +1,5 @@
1
1
  <div align="center">
2
-
2
+
3
3
  ![quanta-intellect-logo-transparent](https://cdn-uploads.huggingface.co/production/uploads/686c460ba3fc457ad14ab6f8/gB6J60f9Yeyb3Thop2dUa.png)
4
4
 
5
5
  <a href="https://snapcraft.io/vessel-browser">
@@ -22,11 +22,9 @@ Vessel gives external agent harnesses a real browser with durable state, MCP con
22
22
  *Vessel is in active development and currently makes no security assurances. Use and deploy it with care.*
23
23
 
24
24
 
25
-
26
25
  https://github.com/user-attachments/assets/0a72b48a-873a-4eb0-b8f2-23e34d8472c4
27
26
 
28
27
 
29
-
30
28
  ## Quick Start
31
29
 
32
30
  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).
@@ -80,7 +78,6 @@ Most browser automation stacks are either headless, stateless, or designed aroun
80
78
  <img width="1280" height="800" alt="@quanta-intellectvessel-browser_2026-03-17_195754_6624" src="https://github.com/user-attachments/assets/3b3d2033-5a59-4806-bbc1-359efb7b43a9" />
81
79
 
82
80
 
83
-
84
81
  <img width="1280" height="800" alt="vessel_2026-03-17_145154_5389" src="https://github.com/user-attachments/assets/b1c08d6c-bcdf-4c9a-8429-a71a23a61903" />
85
82
 
86
83
  Vessel is built for persistent web agents that need a real browser, durable state, and a human-visible interface. The agent is the primary operator. The human follows along in the live browser UI, audits what the agent is doing, and steers when needed.
@@ -420,7 +417,7 @@ mcp_servers:
420
417
  connect_timeout: 30
421
418
  ```
422
419
 
423
- ## Configuration
420
+ ## Configuration
424
421
 
425
422
  The installer writes three snippets to:
426
423
 
package/out/main/index.js CHANGED
@@ -3284,6 +3284,7 @@ const Channels = {
3284
3284
  FOLDER_CREATE: "bookmarks:folder-create",
3285
3285
  FOLDER_REMOVE: "bookmarks:folder-remove",
3286
3286
  FOLDER_RENAME: "bookmarks:folder-rename",
3287
+ FOLDER_EXPORT_HTML: "bookmarks:folder-export-html",
3287
3288
  // Highlights
3288
3289
  HIGHLIGHT_CAPTURE: "highlights:capture",
3289
3290
  HIGHLIGHT_CAPTURE_RESULT: "highlights:capture-result",
@@ -11759,6 +11760,41 @@ function exportBookmarksHtml(options = {}) {
11759
11760
  return `${lines.join("\n")}
11760
11761
  `;
11761
11762
  }
11763
+ function exportBookmarkFolderHtml(folderId, options = {}) {
11764
+ const current = getState();
11765
+ const folder = current.folders.find((item) => item.id === folderId);
11766
+ if (!folder) return null;
11767
+ const resolvedOptions = {
11768
+ includeNotes: options.includeNotes ?? false
11769
+ };
11770
+ const now = Math.floor(Date.now() / 1e3);
11771
+ const items = current.bookmarks.filter(
11772
+ (bookmark) => bookmark.folderId === folder.id
11773
+ );
11774
+ const addDate = toNetscapeTimestamp(folder.createdAt) || now;
11775
+ const lines = [
11776
+ NETSCAPE_BOOKMARKS_DOCTYPE,
11777
+ '<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">',
11778
+ `<TITLE>${escapeBookmarkHtml(folder.name)}</TITLE>`,
11779
+ `<H1>${escapeBookmarkHtml(folder.name)}</H1>`,
11780
+ "<DL><p>",
11781
+ ` <DT><H3 ADD_DATE="${addDate}" LAST_MODIFIED="${now}">${escapeBookmarkHtml(folder.name)}</H3>`
11782
+ ];
11783
+ if (resolvedOptions.includeNotes && folder.summary) {
11784
+ lines.push(` <DD>${escapeBookmarkHtml(folder.summary)}`);
11785
+ }
11786
+ lines.push(" <DL><p>");
11787
+ for (const bookmark of items) {
11788
+ appendBookmarkHtml(lines, bookmark, resolvedOptions, " ");
11789
+ }
11790
+ lines.push(" </DL><p>", "</DL><p>");
11791
+ return {
11792
+ content: `${lines.join("\n")}
11793
+ `,
11794
+ count: items.length,
11795
+ folderName: folder.name
11796
+ };
11797
+ }
11762
11798
  function exportBookmarksJson() {
11763
11799
  return `${JSON.stringify(getState(), null, 2)}
11764
11800
  `;
@@ -23941,8 +23977,7 @@ const THIRD_PARTY_PATH_PATTERNS = [
23941
23977
  /\/beacon/i,
23942
23978
  /\/pixel/i
23943
23979
  ];
23944
- let installed = false;
23945
- const defaultSessionTabManagers = /* @__PURE__ */ new Set();
23980
+ const EMPTY_BLOCKED_FRAME_URL = "data:text/html;charset=utf-8,%3C!doctype%20html%3E%3Chtml%3E%3Cbody%3E%3C!--%20blocked%20by%20Vessel%20ad%20blocker%20--%3E%3C%2Fbody%3E%3C%2Fhtml%3E";
23946
23981
  function normalizeHostname(value) {
23947
23982
  return value.trim().toLowerCase().replace(/\.$/, "");
23948
23983
  }
@@ -23980,11 +24015,20 @@ function shouldBlockRequest(details) {
23980
24015
  if (BLOCKED_HOST_SUFFIXES.some((suffix) => hostnameMatches(hostname, suffix))) {
23981
24016
  return true;
23982
24017
  }
23983
- const firstPartyHost = parseHostname(details.referrer) || parseHostname(details.initiator || "");
24018
+ const firstPartyHost = parseHostname(details.referrer || "") || parseHostname(details.initiator || "");
23984
24019
  if (!isThirdParty(parsed, firstPartyHost)) return false;
23985
24020
  const candidate = `${hostname}${parsed.pathname}${parsed.search}`;
23986
24021
  return THIRD_PARTY_PATH_PATTERNS.some((pattern) => pattern.test(candidate));
23987
24022
  }
24023
+ function getAdBlockDecision(details) {
24024
+ if (!shouldBlockRequest(details)) return { cancel: false };
24025
+ if (details.resourceType === "subFrame") {
24026
+ return { redirectURL: EMPTY_BLOCKED_FRAME_URL };
24027
+ }
24028
+ return { cancel: true };
24029
+ }
24030
+ let installed = false;
24031
+ const defaultSessionTabManagers = /* @__PURE__ */ new Set();
23988
24032
  function installAdBlocking(tabManager) {
23989
24033
  defaultSessionTabManagers.add(tabManager);
23990
24034
  if (installed) return;
@@ -24002,7 +24046,7 @@ function installAdBlocking(tabManager) {
24002
24046
  callback({});
24003
24047
  return;
24004
24048
  }
24005
- callback({ cancel: shouldBlockRequest(details) });
24049
+ callback(getAdBlockDecision(details));
24006
24050
  });
24007
24051
  }
24008
24052
  function unregisterAdBlockingTabManager(tabManager) {
@@ -24019,7 +24063,7 @@ function installAdBlockingForSession(ses, tabManager) {
24019
24063
  callback({});
24020
24064
  return;
24021
24065
  }
24022
- callback({ cancel: shouldBlockRequest(details) });
24066
+ callback(getAdBlockDecision(details));
24023
24067
  });
24024
24068
  }
24025
24069
  const defaultDownloadViews = /* @__PURE__ */ new Set();
@@ -24742,6 +24786,10 @@ function createSecondaryWindow() {
24742
24786
  win.show();
24743
24787
  return state2;
24744
24788
  }
24789
+ function getSafeBookmarkExportName(name) {
24790
+ const safeName = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
24791
+ return safeName || "folder";
24792
+ }
24745
24793
  function registerBookmarkHandlers() {
24746
24794
  electron.ipcMain.handle(Channels.BOOKMARKS_GET, () => {
24747
24795
  return getState();
@@ -24820,6 +24868,29 @@ function registerBookmarkHandlers() {
24820
24868
  count: getState().bookmarks.length
24821
24869
  };
24822
24870
  });
24871
+ electron.ipcMain.handle(
24872
+ Channels.FOLDER_EXPORT_HTML,
24873
+ async (_, folderId, options) => {
24874
+ const folder = getFolder(folderId);
24875
+ if (!folder) return null;
24876
+ const { canceled, filePath } = await electron.dialog.showSaveDialog({
24877
+ title: `Export ${folder.name}`,
24878
+ defaultPath: `vessel-bookmarks-${getSafeBookmarkExportName(folder.name)}.html`,
24879
+ filters: [{ name: "HTML Bookmarks", extensions: ["html"] }]
24880
+ });
24881
+ if (canceled || !filePath) return null;
24882
+ const result = exportBookmarkFolderHtml(folderId, {
24883
+ includeNotes: options?.includeNotes ?? true
24884
+ });
24885
+ if (!result) return null;
24886
+ await fs.promises.writeFile(filePath, result.content, "utf-8");
24887
+ trackBookmarkAction("export");
24888
+ return {
24889
+ filePath,
24890
+ count: result.count
24891
+ };
24892
+ }
24893
+ );
24823
24894
  electron.ipcMain.handle(Channels.BOOKMARKS_IMPORT_HTML, async () => {
24824
24895
  const { canceled, filePaths } = await electron.dialog.showOpenDialog({
24825
24896
  title: "Import Bookmarks",
@@ -67,6 +67,7 @@ const Channels = {
67
67
  FOLDER_CREATE: "bookmarks:folder-create",
68
68
  FOLDER_REMOVE: "bookmarks:folder-remove",
69
69
  FOLDER_RENAME: "bookmarks:folder-rename",
70
+ FOLDER_EXPORT_HTML: "bookmarks:folder-export-html",
70
71
  // Highlights
71
72
  HIGHLIGHT_CAPTURE: "highlights:capture",
72
73
  HIGHLIGHT_CAPTURE_RESULT: "highlights:capture-result",
@@ -359,6 +360,7 @@ const api = {
359
360
  removeBookmark: (id) => electron.ipcRenderer.invoke(Channels.BOOKMARK_REMOVE, id),
360
361
  exportHtml: (options) => electron.ipcRenderer.invoke(Channels.BOOKMARKS_EXPORT_HTML, options),
361
362
  exportJson: () => electron.ipcRenderer.invoke(Channels.BOOKMARKS_EXPORT_JSON),
363
+ exportFolderHtml: (folderId, options) => electron.ipcRenderer.invoke(Channels.FOLDER_EXPORT_HTML, folderId, options),
362
364
  importHtml: () => electron.ipcRenderer.invoke(Channels.BOOKMARKS_IMPORT_HTML),
363
365
  importJson: () => electron.ipcRenderer.invoke(Channels.BOOKMARKS_IMPORT_JSON),
364
366
  createFolder: (name) => electron.ipcRenderer.invoke(Channels.FOLDER_CREATE, name),
@@ -2752,6 +2752,7 @@ function useBookmarks() {
2752
2752
  removeBookmark: (id) => window.vessel.bookmarks.removeBookmark(id),
2753
2753
  exportHtml: (options) => window.vessel.bookmarks.exportHtml(options),
2754
2754
  exportJson: () => window.vessel.bookmarks.exportJson(),
2755
+ exportFolderHtml: (folderId, options) => window.vessel.bookmarks.exportFolderHtml(folderId, options),
2755
2756
  createFolder: (name) => window.vessel.bookmarks.createFolder(name),
2756
2757
  createFolderWithSummary: (name, summary) => window.vessel.bookmarks.createFolderWithSummary(name, summary),
2757
2758
  removeFolder: (id, deleteContents) => window.vessel.bookmarks.removeFolder(id, deleteContents),
@@ -2881,15 +2882,16 @@ function cleanDiffSummaryText(value) {
2881
2882
  return value.replace(
2882
2883
  /```[\s\S]*?```/g,
2883
2884
  (match) => match.replace(/```[a-z]*\n?/gi, "").replace(/```/g, "")
2884
- ).replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/(\*\*|__)(.*?)\1/g, "$2").replace(/(\*|_)(.*?)\1/g, "$2").replace(/^#{1,6}\s+/gm, "").replace(/^\s*[-*+]\s+/gm, "").replace(/^\s*>\s?/gm, "").replace(/\s+/g, " ").trim();
2885
+ ).replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/(\*\*|__)(.*?)\1/g, "$2").replace(/(\*|_)(.*?)\1/g, "$2").replace(/^\s*>\s?/gm, "").replace(/^#{1,6}\s+/gm, "").replace(/^\s*[-*+]\s+/gm, "").replace(/\s+/g, " ").trim();
2885
2886
  }
2886
2887
  function formatDiffSectionLabel(section) {
2887
- const normalized = section.trim().toLowerCase();
2888
- return SECTION_LABELS[normalized] ?? section.trim();
2888
+ const trimmed = section.trim();
2889
+ const normalized = trimmed.toLowerCase();
2890
+ return SECTION_LABELS[normalized] ?? trimmed;
2889
2891
  }
2890
2892
  function parseDiffSummaryParts(summary) {
2891
- return summary.split(/\s+\|\s+/).map((part) => {
2892
- const match = part.match(/^([a-z]+):\s*(.+)$/i);
2893
+ const parts = summary.split(/\s*\|\s*/).map((part) => {
2894
+ const match = part.match(/^([a-z][a-z\s-]*):\s*(.+)$/i);
2893
2895
  if (!match) {
2894
2896
  return { text: cleanDiffSummaryText(part) };
2895
2897
  }
@@ -2898,6 +2900,48 @@ function parseDiffSummaryParts(summary) {
2898
2900
  text: cleanDiffSummaryText(match[2])
2899
2901
  };
2900
2902
  }).filter((part) => part.text.length > 0);
2903
+ return parts.length > 0 ? parts : [{ text: "Change detected." }];
2904
+ }
2905
+ function resolveNow(options) {
2906
+ if (options?.now instanceof Date) return options.now.getTime();
2907
+ return Date.now();
2908
+ }
2909
+ function formatRelativeTime(isoDate, options) {
2910
+ const timestamp = new Date(isoDate).getTime();
2911
+ if (Number.isNaN(timestamp)) return "recently";
2912
+ const now2 = resolveNow(options);
2913
+ if (Number.isNaN(now2)) return "recently";
2914
+ const diff = Math.max(0, now2 - timestamp);
2915
+ const mins = Math.floor(diff / 6e4);
2916
+ if (mins < 1) return "just now";
2917
+ if (mins < 60) return `${mins}m ago`;
2918
+ const hours = Math.floor(mins / 60);
2919
+ if (hours < 24) return `${hours}h ago`;
2920
+ const days = Math.floor(hours / 24);
2921
+ if (days < 7) return `${days}d ago`;
2922
+ return new Date(timestamp).toLocaleDateString();
2923
+ }
2924
+ function formatShortDateTime(isoDate) {
2925
+ const date = new Date(isoDate);
2926
+ if (Number.isNaN(date.getTime())) return "Unknown time";
2927
+ return date.toLocaleString([], {
2928
+ month: "short",
2929
+ day: "numeric",
2930
+ hour: "numeric",
2931
+ minute: "2-digit"
2932
+ });
2933
+ }
2934
+ function formatElapsedTime(startIso, endIso) {
2935
+ const start = new Date(startIso).getTime();
2936
+ const end = new Date(endIso).getTime();
2937
+ if (Number.isNaN(start) || Number.isNaN(end)) return "unknown duration";
2938
+ const elapsedMs = Math.max(0, end - start);
2939
+ const secs = Math.round(elapsedMs / 1e3);
2940
+ if (secs < 60) return `${secs}s`;
2941
+ const mins = Math.round(secs / 60);
2942
+ if (mins < 60) return `${mins}m`;
2943
+ const hours = Math.round(mins / 60);
2944
+ return `${hours}h`;
2901
2945
  }
2902
2946
  const SEARCH_ENGINE_PRESETS = {
2903
2947
  duckduckgo: { label: "DuckDuckGo", url: "https://duckduckgo.com/?q=" },
@@ -2942,8 +2986,14 @@ const AddressBar = (props) => {
2942
2986
  const [selectedIndex, setSelectedIndex] = createSignal(-1);
2943
2987
  const [searchEngine, setSearchEngine] = createSignal("duckduckgo");
2944
2988
  const [showSecurityPopup, setShowSecurityPopup] = createSignal(false);
2989
+ const [hasEditedAddress, setHasEditedAddress] = createSignal(false);
2945
2990
  const now2 = useNow();
2946
2991
  let inputRef;
2992
+ let addressBlurTimer = null;
2993
+ let skipNextAddressBlurSync = false;
2994
+ onCleanup(() => {
2995
+ if (addressBlurTimer) clearTimeout(addressBlurTimer);
2996
+ });
2947
2997
  const securityState = createMemo(() => {
2948
2998
  const tabId = activeTabId2();
2949
2999
  return tabId ? getSecurityState(tabId) : void 0;
@@ -2994,26 +3044,6 @@ const AddressBar = (props) => {
2994
3044
  }
2995
3045
  await window.vessel.ui.openSidebarTab("diff");
2996
3046
  };
2997
- const formatRelativeTime2 = (isoDate) => {
2998
- const diff = Date.now() - new Date(isoDate).getTime();
2999
- const mins = Math.floor(diff / 6e4);
3000
- if (mins < 1) return "just now";
3001
- if (mins < 60) return `${mins}m ago`;
3002
- const hours = Math.floor(mins / 60);
3003
- if (hours < 24) return `${hours}h ago`;
3004
- const days = Math.floor(hours / 24);
3005
- if (days < 7) return `${days}d ago`;
3006
- return new Date(isoDate).toLocaleDateString();
3007
- };
3008
- const formatElapsed = (startIso, endIso) => {
3009
- const elapsedMs = Math.max(0, new Date(endIso).getTime() - new Date(startIso).getTime());
3010
- const secs = Math.round(elapsedMs / 1e3);
3011
- if (secs < 60) return `${secs}s`;
3012
- const mins = Math.round(secs / 60);
3013
- if (mins < 60) return `${mins}m`;
3014
- const hours = Math.round(mins / 60);
3015
- return `${hours}h`;
3016
- };
3017
3047
  const getChangeKindLabel = (kind) => kind === "added" ? "Added" : kind === "removed" ? "Removed" : "Changed";
3018
3048
  createEffect(() => {
3019
3049
  if (isPrivateWindow) return;
@@ -3031,10 +3061,16 @@ const AddressBar = (props) => {
3031
3061
  }
3032
3062
  });
3033
3063
  });
3064
+ const syncInputValueFromActiveTab = () => {
3065
+ const tab = activeTab();
3066
+ if (!tab) return;
3067
+ setInputValue(tab.url === "about:blank" ? "" : tab.url);
3068
+ };
3034
3069
  createEffect(() => {
3035
3070
  const tab = activeTab();
3036
- if (tab && !inputRef?.matches(":focus")) {
3037
- setInputValue(tab.url === "about:blank" ? "" : tab.url);
3071
+ const inputHasFocus = inputRef && document.activeElement === inputRef;
3072
+ if (tab && !hasEditedAddress() && !inputHasFocus) {
3073
+ syncInputValueFromActiveTab();
3038
3074
  setShowSuggestions(false);
3039
3075
  setSelectedIndex(-1);
3040
3076
  }
@@ -3117,12 +3153,46 @@ const AddressBar = (props) => {
3117
3153
  cancelled = true;
3118
3154
  });
3119
3155
  });
3120
- const selectSuggestion = (url) => {
3121
- setInputValue(url);
3156
+ const clearAddressBlurTimer = () => {
3157
+ if (!addressBlurTimer) return;
3158
+ clearTimeout(addressBlurTimer);
3159
+ addressBlurTimer = null;
3160
+ };
3161
+ const closeAddressSuggestions = () => {
3122
3162
  setShowSuggestions(false);
3123
3163
  setSelectedIndex(-1);
3164
+ };
3165
+ const commitAddressNavigation = (url) => {
3166
+ clearAddressBlurTimer();
3167
+ setHasEditedAddress(false);
3168
+ skipNextAddressBlurSync = true;
3124
3169
  navigate(url);
3125
3170
  inputRef?.blur();
3171
+ closeAddressSuggestions();
3172
+ };
3173
+ const cancelAddressEditing = () => {
3174
+ clearAddressBlurTimer();
3175
+ setHasEditedAddress(false);
3176
+ syncInputValueFromActiveTab();
3177
+ inputRef?.blur();
3178
+ closeAddressSuggestions();
3179
+ };
3180
+ const scheduleAddressBlurReset = () => {
3181
+ clearAddressBlurTimer();
3182
+ addressBlurTimer = setTimeout(() => {
3183
+ setHasEditedAddress(false);
3184
+ if (skipNextAddressBlurSync) {
3185
+ skipNextAddressBlurSync = false;
3186
+ } else {
3187
+ syncInputValueFromActiveTab();
3188
+ }
3189
+ closeAddressSuggestions();
3190
+ addressBlurTimer = null;
3191
+ }, 150);
3192
+ };
3193
+ const selectSuggestion = (url) => {
3194
+ setInputValue(url);
3195
+ commitAddressNavigation(url);
3126
3196
  };
3127
3197
  const handleSubmit = (e) => {
3128
3198
  e.preventDefault();
@@ -3132,11 +3202,7 @@ const AddressBar = (props) => {
3132
3202
  selectSuggestion(items[idx].url);
3133
3203
  } else {
3134
3204
  const val = inputValue().trim();
3135
- if (val) {
3136
- navigate(val);
3137
- inputRef?.blur();
3138
- setShowSuggestions(false);
3139
- }
3205
+ if (val) commitAddressNavigation(val);
3140
3206
  }
3141
3207
  };
3142
3208
  const handleInputKeyDown = (e) => {
@@ -3156,10 +3222,11 @@ const AddressBar = (props) => {
3156
3222
  }
3157
3223
  } else if (e.key === "Escape") {
3158
3224
  if (showSuggestions()) {
3159
- setShowSuggestions(false);
3160
- setSelectedIndex(-1);
3225
+ syncInputValueFromActiveTab();
3226
+ setHasEditedAddress(false);
3227
+ closeAddressSuggestions();
3161
3228
  } else {
3162
- inputRef?.blur();
3229
+ cancelAddressEditing();
3163
3230
  }
3164
3231
  }
3165
3232
  };
@@ -3242,18 +3309,17 @@ const AddressBar = (props) => {
3242
3309
  }), _el$11);
3243
3310
  _el$12.addEventListener("submit", handleSubmit);
3244
3311
  _el$13.addEventListener("blur", () => {
3245
- setTimeout(() => {
3246
- setShowSuggestions(false);
3247
- setSelectedIndex(-1);
3248
- }, 150);
3312
+ scheduleAddressBlurReset();
3249
3313
  });
3250
3314
  _el$13.$$keydown = handleInputKeyDown;
3251
3315
  _el$13.addEventListener("focus", (e) => {
3316
+ clearAddressBlurTimer();
3252
3317
  e.currentTarget.select();
3253
3318
  const query = inputValue().trim();
3254
3319
  if (query.length >= 2) setShowSuggestions(true);
3255
3320
  });
3256
3321
  _el$13.$$input = (e) => {
3322
+ setHasEditedAddress(true);
3257
3323
  setInputValue(e.currentTarget.value);
3258
3324
  setShowSuggestions(true);
3259
3325
  setSelectedIndex(-1);
@@ -3336,7 +3402,7 @@ const AddressBar = (props) => {
3336
3402
  var _el$19 = _tmpl$0$5(), _el$20 = _el$19.firstChild, _el$21 = _el$20.firstChild, _el$22 = _el$21.firstChild, _el$23 = _el$22.nextSibling;
3337
3403
  _el$23.firstChild;
3338
3404
  var _el$30 = _el$21.nextSibling, _el$31 = _el$30.firstChild, _el$32 = _el$31.nextSibling;
3339
- insert(_el$23, () => formatRelativeTime2(pageDiff().oldSnapshot.capturedAt), null);
3405
+ insert(_el$23, () => formatRelativeTime(pageDiff().oldSnapshot.capturedAt), null);
3340
3406
  insert(_el$21, createComponent(Show, {
3341
3407
  get when() {
3342
3408
  return memo(() => !!((pageDiff().burstCount || 0) > 1 && pageDiff().firstDetectedAt))() && pageDiff().lastDetectedAt;
@@ -3345,7 +3411,7 @@ const AddressBar = (props) => {
3345
3411
  var _el$25 = _tmpl$8$8(), _el$26 = _el$25.firstChild, _el$29 = _el$26.nextSibling;
3346
3412
  _el$29.nextSibling;
3347
3413
  insert(_el$25, () => pageDiff().burstCount, _el$29);
3348
- insert(_el$25, () => formatElapsed(pageDiff().firstDetectedAt, pageDiff().lastDetectedAt), null);
3414
+ insert(_el$25, () => formatElapsedTime(pageDiff().firstDetectedAt, pageDiff().lastDetectedAt), null);
3349
3415
  return _el$25;
3350
3416
  }
3351
3417
  }), null);
@@ -3366,7 +3432,7 @@ const AddressBar = (props) => {
3366
3432
  var _el$55 = _tmpl$20$2(), _el$56 = _el$55.firstChild, _el$57 = _el$56.nextSibling;
3367
3433
  insert(_el$56, (() => {
3368
3434
  var _c$2 = memo(() => i() === 0);
3369
- return () => _c$2() ? "Latest" : formatRelativeTime2(burst.detectedAt);
3435
+ return () => _c$2() ? "Latest" : formatRelativeTime(burst.detectedAt);
3370
3436
  })());
3371
3437
  insert(_el$57, createComponent(For, {
3372
3438
  get each() {
@@ -7313,23 +7379,6 @@ const AutomationTab = (props) => {
7313
7379
  };
7314
7380
  delegateEvents(["click", "input", "keydown", "contextmenu"]);
7315
7381
  var _tmpl$$b = /* @__PURE__ */ template(`<div class=agent-muted>Loading...`), _tmpl$2$b = /* @__PURE__ */ template(`<div class=agent-muted>`), _tmpl$3$a = /* @__PURE__ */ template(`<div class=agent-muted>No changes detected yet.`), _tmpl$4$a = /* @__PURE__ */ template(`<div class=page-diff-timeline-header><div class=agent-section-title>Change history for this page</div><div class=agent-muted>Newest detections are first. Each entry is a saved change burst.`), _tmpl$5$7 = /* @__PURE__ */ template(`<div class=page-diff-history-list>`), _tmpl$6$7 = /* @__PURE__ */ template(`<div class=page-diff-timeline>`), _tmpl$7$7 = /* @__PURE__ */ template(`<div class=page-diff-history-item><div class=page-diff-history-time><span class=page-diff-history-label></span><span></span></div><div class=page-diff-history-card><div class=page-diff-history-summary-list></div><div class=page-diff-history-position>Entry <!> of `), _tmpl$8$6 = /* @__PURE__ */ template(`<span class=page-diff-history-summary-section>`), _tmpl$9$4 = /* @__PURE__ */ template(`<div class=page-diff-history-summary-row><span class=page-diff-history-summary>`);
7316
- const formatChangeTime = (isoDate) => new Date(isoDate).toLocaleString([], {
7317
- month: "short",
7318
- day: "numeric",
7319
- hour: "numeric",
7320
- minute: "2-digit"
7321
- });
7322
- const formatRelativeTime = (isoDate) => {
7323
- const diff = Date.now() - new Date(isoDate).getTime();
7324
- const mins = Math.floor(diff / 6e4);
7325
- if (mins < 1) return "just now";
7326
- if (mins < 60) return `${mins}m ago`;
7327
- const hours = Math.floor(mins / 60);
7328
- if (hours < 24) return `${hours}h ago`;
7329
- const days = Math.floor(hours / 24);
7330
- if (days < 7) return `${days}d ago`;
7331
- return new Date(isoDate).toLocaleDateString();
7332
- };
7333
7382
  const PageDiffTimeline = () => {
7334
7383
  const {
7335
7384
  activeTab
@@ -7426,7 +7475,7 @@ const PageDiffTimeline = () => {
7426
7475
  var _c$ = memo(() => i() === 0);
7427
7476
  return () => _c$() ? "Latest change" : formatRelativeTime(burst.detectedAt);
7428
7477
  })());
7429
- insert(_el$0, () => formatChangeTime(burst.detectedAt));
7478
+ insert(_el$0, () => formatShortDateTime(burst.detectedAt));
7430
7479
  insert(_el$10, createComponent(For, {
7431
7480
  get each() {
7432
7481
  return parseDiffSummaryParts(burst.summary);
@@ -7460,7 +7509,7 @@ const PageDiffTimeline = () => {
7460
7509
  })();
7461
7510
  };
7462
7511
  const vesselLogo = "" + new URL("vessel-logo-transparent-IT25qr-Z.png", import.meta.url).href;
7463
- var _tmpl$$a = /* @__PURE__ */ template(`<div class="message-content markdown-content">`), _tmpl$2$a = /* @__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$9 = /* @__PURE__ */ template(`<span class=sidebar-tab-badge>`), _tmpl$4$9 = /* @__PURE__ */ template(`<button class=agent-primary-button type=button>Undo last action`), _tmpl$5$6 = /* @__PURE__ */ template(`<div class=agent-section-title>Pending approvals`), _tmpl$6$6 = /* @__PURE__ */ template(`<button class=agent-section-toggle type=button>`), _tmpl$7$6 = /* @__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$8$5 = /* @__PURE__ */ template(`<span class=bookmark-status-pill>Saved`), _tmpl$9$3 = /* @__PURE__ */ template(`<div class=bookmark-export-message>`), _tmpl$0$3 = /* @__PURE__ */ template(`<div class=bookmark-save-body><div class=bookmark-export-actions><button class=bookmark-secondary-button type=button>Import HTML</button><button class=bookmark-secondary-button type=button>Import JSON`), _tmpl$1$3 = /* @__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></textarea><textarea class=bookmark-note-input placeholder="Intent: what is this page for?"rows=1></textarea><textarea class=bookmark-note-input placeholder="Expected content: what should be here?"rows=1></textarea><input class=bookmark-input placeholder="Key fields (comma-separated)"><textarea class=bookmark-note-input placeholder="Agent hints (one key:value per line)"rows=2>`), _tmpl$10$3 = /* @__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-export-card><div><div class=bookmark-panel-title>Export</div><div class=bookmark-panel-subtitle>Save browser-ready HTML or a full Vessel archive</div></div><div class=bookmark-export-actions><button class=bookmark-secondary-button type=button>Browser HTML</button><button class=bookmark-secondary-button type=button>HTML + notes</button><button class=bookmark-secondary-button type=button>Vessel JSON</button></div></div><div class=bookmark-import-shell><button class=bookmark-save-toggle type=button><span class=bookmark-save-toggle-copy><span class=bookmark-save-toggle-title>Import Bookmarks</span><span class=bookmark-save-toggle-subtitle>Import from HTML or Vessel JSON</span></span><span class=bookmark-save-toggle-caret aria-hidden=true>▾</span></button></div><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$11$3 = /* @__PURE__ */ template(`<div class=checkpoint-timeline>`), _tmpl$12$3 = /* @__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"><textarea class=agent-textarea rows=2 placeholder="Optional note for this checkpoint"></textarea><button class=agent-primary-button type=button>Save checkpoint</button></div><div class=agent-section-title>Recent checkpoints`), _tmpl$13$2 = /* @__PURE__ */ template(`<p class=history-empty>No browsing history yet.`), _tmpl$14$2 = /* @__PURE__ */ template(`<div class=history-panel><div class=history-panel-header><span class=history-panel-title>Browsing History</span><div class=history-panel-actions><button class=history-clear-btn>Clear</button><button class=history-clear-btn>Export HTML</button><button class=history-clear-btn>Export JSON</button><button class=history-clear-btn>Import</button></div></div><div class=history-list>`), _tmpl$15$2 = /* @__PURE__ */ template(`<section class=agent-panel><div class=agent-panel-header><div class=agent-panel-title>What Changed</div><div class=agent-panel-subtitle>`), _tmpl$16$1 = /* @__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$17$1 = /* @__PURE__ */ template(`<span>`), _tmpl$18$1 = /* @__PURE__ */ template(`<div><div class=streaming-status><span class=streaming-pulse aria-hidden=true></span><span>Generating`), _tmpl$19$1 = /* @__PURE__ */ template(`<div class="message message-assistant"><div class=message-content>`), _tmpl$20 = /* @__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$21 = /* @__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$22 = /* @__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$23 = /* @__PURE__ */ template(`<div class=chat-actions>`), _tmpl$24 = /* @__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$25 = /* @__PURE__ */ template(`<button class=chat-queue-clear type=button>Clear queue`), _tmpl$26 = /* @__PURE__ */ template(`<div class=chat-queue-list>`), _tmpl$27 = /* @__PURE__ */ template(`<div class=chat-queue-status><div class=chat-queue-status-row><span>`), _tmpl$28 = /* @__PURE__ */ template(`<div class=sidebar-input-area><textarea class=sidebar-input rows=2></textarea><button class=sidebar-send>`), _tmpl$29 = /* @__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><button class=sidebar-tab role=tab>History</button><button class=sidebar-tab role=tab>Changes</button></div><div class=sidebar-messages><div>`), _tmpl$30 = /* @__PURE__ */ template(`<div class=agent-muted>No pending approvals.`), _tmpl$31 = /* @__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$32 = /* @__PURE__ */ template(`<div class=agent-muted>No actions yet.`), _tmpl$33 = /* @__PURE__ */ template(`<div class=agent-muted>Recent actions are collapsed to reduce noise.`), _tmpl$34 = /* @__PURE__ */ template(`<div class="agent-card-copy success">`), _tmpl$35 = /* @__PURE__ */ template(`<div class="agent-card-copy error">`), _tmpl$36 = /* @__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$37 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>`), _tmpl$38 = /* @__PURE__ */ template(`<div class=bookmark-folder-summary>`), _tmpl$39 = /* @__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$40 = /* @__PURE__ */ template(`<button class=bookmark-ghost-button type=button>Keep bookmarks`), _tmpl$41 = /* @__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$42 = /* @__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$43 = /* @__PURE__ */ template(`<div class=bookmark-items>`), _tmpl$44 = /* @__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$45 = /* @__PURE__ */ template(`<div class=bookmark-folder-collapsed-hint>Click to view saved links.`), _tmpl$46 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>No bookmarks in this folder yet.`), _tmpl$47 = /* @__PURE__ */ template(`<div class=bookmark-item-note>`), _tmpl$48 = /* @__PURE__ */ template(`<div><strong>Intent:</strong> `), _tmpl$49 = /* @__PURE__ */ template(`<div><strong>Expected:</strong> `), _tmpl$50 = /* @__PURE__ */ template(`<div><strong>Key fields:</strong> `), _tmpl$51 = /* @__PURE__ */ template(`<div><strong>Hints:</strong> `), _tmpl$52 = /* @__PURE__ */ template(`<div class=bookmark-folder-edit><input class=bookmark-input placeholder="Bookmark title"><textarea class=bookmark-note-input rows=2 placeholder="Why this bookmark matters"></textarea><textarea class=bookmark-note-input rows=1 placeholder=Intent></textarea><textarea class=bookmark-note-input rows=1 placeholder="Expected content"></textarea><input class=bookmark-input placeholder="Key fields (comma-separated)"><textarea class=bookmark-note-input rows=2 placeholder="Agent hints (one key:value per line)"></textarea><div class=bookmark-item-footer><button class=bookmark-secondary-button type=button>Save edits</button><button class=bookmark-ghost-button type=button>Cancel`), _tmpl$53 = /* @__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 type=button></button><button class="bookmark-ghost-button danger"type=button>Remove`), _tmpl$54 = /* @__PURE__ */ template(`<div class=agent-muted>No checkpoints yet.`), _tmpl$55 = /* @__PURE__ */ template(`<span class=checkpoint-timeline-line>`), _tmpl$56 = /* @__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><textarea class=agent-textarea rows=2 placeholder="Add a note..."></textarea><button class=agent-control-button type=button>Restore`), _tmpl$57 = /* @__PURE__ */ template(`<button class=history-entry><span class=history-entry-title></span><span class=history-entry-url></span><span class=history-entry-time>`), _tmpl$58 = /* @__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">The Diff timeline is a premium feature. Upgrade to see a full history of what changed on this page.</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$59 = /* @__PURE__ */ template(`<div>`), _tmpl$60 = /* @__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$61 = /* @__PURE__ */ template(`<div class=chat-approval-detail>`), _tmpl$62 = /* @__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$63 = /* @__PURE__ */ template(`<div class=chat-queue-item><span class=chat-queue-text></span><button class=chat-queue-remove type=button>×`);
7512
+ var _tmpl$$a = /* @__PURE__ */ template(`<div class="message-content markdown-content">`), _tmpl$2$a = /* @__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$9 = /* @__PURE__ */ template(`<span class=sidebar-tab-badge>`), _tmpl$4$9 = /* @__PURE__ */ template(`<button class=agent-primary-button type=button>Undo last action`), _tmpl$5$6 = /* @__PURE__ */ template(`<div class=agent-section-title>Pending approvals`), _tmpl$6$6 = /* @__PURE__ */ template(`<button class=agent-section-toggle type=button>`), _tmpl$7$6 = /* @__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$8$5 = /* @__PURE__ */ template(`<span class=bookmark-status-pill>Saved`), _tmpl$9$3 = /* @__PURE__ */ template(`<div class=bookmark-export-message>`), _tmpl$0$3 = /* @__PURE__ */ template(`<div class=bookmark-save-body><div class=bookmark-export-actions><button class=bookmark-secondary-button type=button>Import HTML</button><button class=bookmark-secondary-button type=button>Import JSON`), _tmpl$1$3 = /* @__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></textarea><textarea class=bookmark-note-input placeholder="Intent: what is this page for?"rows=1></textarea><textarea class=bookmark-note-input placeholder="Expected content: what should be here?"rows=1></textarea><input class=bookmark-input placeholder="Key fields (comma-separated)"><textarea class=bookmark-note-input placeholder="Agent hints (one key:value per line)"rows=2>`), _tmpl$10$3 = /* @__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-export-card><div><div class=bookmark-panel-title>Export</div><div class=bookmark-panel-subtitle>Save browser-ready HTML or a full Vessel archive</div></div><div class=bookmark-export-actions><button class=bookmark-secondary-button type=button>Browser HTML</button><button class=bookmark-secondary-button type=button>HTML + notes</button><button class=bookmark-secondary-button type=button>Vessel JSON</button></div></div><div class=bookmark-import-shell><button class=bookmark-save-toggle type=button><span class=bookmark-save-toggle-copy><span class=bookmark-save-toggle-title>Import Bookmarks</span><span class=bookmark-save-toggle-subtitle>Import from HTML or Vessel JSON</span></span><span class=bookmark-save-toggle-caret aria-hidden=true>▾</span></button></div><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$11$3 = /* @__PURE__ */ template(`<div class=checkpoint-timeline>`), _tmpl$12$3 = /* @__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"><textarea class=agent-textarea rows=2 placeholder="Optional note for this checkpoint"></textarea><button class=agent-primary-button type=button>Save checkpoint</button></div><div class=agent-section-title>Recent checkpoints`), _tmpl$13$2 = /* @__PURE__ */ template(`<p class=history-empty>No browsing history yet.`), _tmpl$14$2 = /* @__PURE__ */ template(`<div class=history-panel><div class=history-panel-header><span class=history-panel-title>Browsing History</span><div class=history-panel-actions><button class=history-clear-btn>Clear</button><button class=history-clear-btn>Export HTML</button><button class=history-clear-btn>Export JSON</button><button class=history-clear-btn>Import</button></div></div><div class=history-list>`), _tmpl$15$2 = /* @__PURE__ */ template(`<section class=agent-panel><div class=agent-panel-header><div class=agent-panel-title>What Changed</div><div class=agent-panel-subtitle>`), _tmpl$16$1 = /* @__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$17$1 = /* @__PURE__ */ template(`<span>`), _tmpl$18$1 = /* @__PURE__ */ template(`<div><div class=streaming-status><span class=streaming-pulse aria-hidden=true></span><span>Generating`), _tmpl$19$1 = /* @__PURE__ */ template(`<div class="message message-assistant"><div class=message-content>`), _tmpl$20 = /* @__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$21 = /* @__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$22 = /* @__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$23 = /* @__PURE__ */ template(`<div class=chat-actions>`), _tmpl$24 = /* @__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$25 = /* @__PURE__ */ template(`<button class=chat-queue-clear type=button>Clear queue`), _tmpl$26 = /* @__PURE__ */ template(`<div class=chat-queue-list>`), _tmpl$27 = /* @__PURE__ */ template(`<div class=chat-queue-status><div class=chat-queue-status-row><span>`), _tmpl$28 = /* @__PURE__ */ template(`<div class=sidebar-input-area><textarea class=sidebar-input rows=2></textarea><button class=sidebar-send>`), _tmpl$29 = /* @__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><button class=sidebar-tab role=tab>History</button><button class=sidebar-tab role=tab>Changes</button></div><div class=sidebar-messages><div>`), _tmpl$30 = /* @__PURE__ */ template(`<div class=agent-muted>No pending approvals.`), _tmpl$31 = /* @__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$32 = /* @__PURE__ */ template(`<div class=agent-muted>No actions yet.`), _tmpl$33 = /* @__PURE__ */ template(`<div class=agent-muted>Recent actions are collapsed to reduce noise.`), _tmpl$34 = /* @__PURE__ */ template(`<div class="agent-card-copy success">`), _tmpl$35 = /* @__PURE__ */ template(`<div class="agent-card-copy error">`), _tmpl$36 = /* @__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$37 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>`), _tmpl$38 = /* @__PURE__ */ template(`<div class=bookmark-folder-summary>`), _tmpl$39 = /* @__PURE__ */ template(`<div class=bookmark-folder-actions><button class=bookmark-ghost-button type=button>Rename</button><button class=bookmark-ghost-button type=button>Export</button><button class="bookmark-ghost-button danger"type=button>Delete`), _tmpl$40 = /* @__PURE__ */ template(`<button class=bookmark-ghost-button type=button>Keep bookmarks`), _tmpl$41 = /* @__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$42 = /* @__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$43 = /* @__PURE__ */ template(`<div class=bookmark-items>`), _tmpl$44 = /* @__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$45 = /* @__PURE__ */ template(`<div class=bookmark-folder-collapsed-hint>Click to view saved links.`), _tmpl$46 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>No bookmarks in this folder yet.`), _tmpl$47 = /* @__PURE__ */ template(`<div class=bookmark-item-note>`), _tmpl$48 = /* @__PURE__ */ template(`<div><strong>Intent:</strong> `), _tmpl$49 = /* @__PURE__ */ template(`<div><strong>Expected:</strong> `), _tmpl$50 = /* @__PURE__ */ template(`<div><strong>Key fields:</strong> `), _tmpl$51 = /* @__PURE__ */ template(`<div><strong>Hints:</strong> `), _tmpl$52 = /* @__PURE__ */ template(`<div class=bookmark-folder-edit><input class=bookmark-input placeholder="Bookmark title"><textarea class=bookmark-note-input rows=2 placeholder="Why this bookmark matters"></textarea><textarea class=bookmark-note-input rows=1 placeholder=Intent></textarea><textarea class=bookmark-note-input rows=1 placeholder="Expected content"></textarea><input class=bookmark-input placeholder="Key fields (comma-separated)"><textarea class=bookmark-note-input rows=2 placeholder="Agent hints (one key:value per line)"></textarea><div class=bookmark-item-footer><button class=bookmark-secondary-button type=button>Save edits</button><button class=bookmark-ghost-button type=button>Cancel`), _tmpl$53 = /* @__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 type=button></button><button class="bookmark-ghost-button danger"type=button>Remove`), _tmpl$54 = /* @__PURE__ */ template(`<div class=agent-muted>No checkpoints yet.`), _tmpl$55 = /* @__PURE__ */ template(`<span class=checkpoint-timeline-line>`), _tmpl$56 = /* @__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><textarea class=agent-textarea rows=2 placeholder="Add a note..."></textarea><button class=agent-control-button type=button>Restore`), _tmpl$57 = /* @__PURE__ */ template(`<button class=history-entry><span class=history-entry-title></span><span class=history-entry-url></span><span class=history-entry-time>`), _tmpl$58 = /* @__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">The Diff timeline is a premium feature. Upgrade to see a full history of what changed on this page.</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$59 = /* @__PURE__ */ template(`<div>`), _tmpl$60 = /* @__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$61 = /* @__PURE__ */ template(`<div class=chat-approval-detail>`), _tmpl$62 = /* @__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$63 = /* @__PURE__ */ template(`<div class=chat-queue-item><span class=chat-queue-text></span><button class=chat-queue-remove type=button>×`);
7464
7513
  const UNSORTED_FOLDER = {
7465
7514
  id: "unsorted",
7466
7515
  name: "Unsorted",
@@ -7545,6 +7594,7 @@ const Sidebar = (props) => {
7545
7594
  removeBookmark,
7546
7595
  exportHtml,
7547
7596
  exportJson,
7597
+ exportFolderHtml,
7548
7598
  createFolderWithSummary,
7549
7599
  removeFolder,
7550
7600
  renameFolder
@@ -8005,6 +8055,24 @@ ${contextBlock}` : contextBlock);
8005
8055
  setEditingFolderSummary("");
8006
8056
  }
8007
8057
  };
8058
+ const handleExportFolder = async (folderId, folderName) => {
8059
+ setBookmarkExporting(true);
8060
+ setBookmarkExportMessage("");
8061
+ try {
8062
+ const result = await exportFolderHtml(folderId, {
8063
+ includeNotes: true
8064
+ });
8065
+ if (!result) {
8066
+ setBookmarkExportMessage("Export canceled.");
8067
+ return;
8068
+ }
8069
+ setBookmarkExportMessage(`Exported ${folderName} (${result.count} bookmarks) to ${result.filePath}`);
8070
+ } catch (error) {
8071
+ setBookmarkExportMessage(error instanceof Error ? error.message : `Could not export ${folderName}.`);
8072
+ } finally {
8073
+ setBookmarkExporting(false);
8074
+ }
8075
+ };
8008
8076
  const handleExportBookmarks = async (format) => {
8009
8077
  setBookmarkExporting(true);
8010
8078
  setBookmarkExportMessage("");
@@ -8360,7 +8428,7 @@ ${contextBlock}` : contextBlock);
8360
8428
  return folder.id !== UNSORTED_FOLDER.id;
8361
8429
  },
8362
8430
  get children() {
8363
- var _el$169 = _tmpl$39(), _el$170 = _el$169.firstChild, _el$171 = _el$170.nextSibling;
8431
+ var _el$169 = _tmpl$39(), _el$170 = _el$169.firstChild, _el$171 = _el$170.nextSibling, _el$172 = _el$171.nextSibling;
8364
8432
  _el$170.$$click = (e) => {
8365
8433
  e.stopPropagation();
8366
8434
  setEditingFolderId(folder.id);
@@ -8368,9 +8436,14 @@ ${contextBlock}` : contextBlock);
8368
8436
  setEditingFolderSummary(folder.summary || "");
8369
8437
  };
8370
8438
  _el$171.$$click = (e) => {
8439
+ e.stopPropagation();
8440
+ void handleExportFolder(folder.id, folder.name);
8441
+ };
8442
+ _el$172.$$click = (e) => {
8371
8443
  e.stopPropagation();
8372
8444
  setDeletingFolderId(folder.id);
8373
8445
  };
8446
+ createRenderEffect(() => _el$171.disabled = bookmarkExporting());
8374
8447
  return _el$169;
8375
8448
  }
8376
8449
  }), null);
@@ -8379,28 +8452,28 @@ ${contextBlock}` : contextBlock);
8379
8452
  return deletingFolderId() === folder.id;
8380
8453
  },
8381
8454
  get children() {
8382
- var _el$172 = _tmpl$41(), _el$173 = _el$172.firstChild, _el$174 = _el$173.firstChild, _el$176 = _el$174.nextSibling;
8383
- _el$176.nextSibling;
8384
- var _el$177 = _el$173.nextSibling, _el$179 = _el$177.firstChild, _el$180 = _el$179.nextSibling;
8385
- insert(_el$173, () => folder.name, _el$176);
8386
- insert(_el$173, (() => {
8455
+ var _el$173 = _tmpl$41(), _el$174 = _el$173.firstChild, _el$175 = _el$174.firstChild, _el$177 = _el$175.nextSibling;
8456
+ _el$177.nextSibling;
8457
+ var _el$178 = _el$174.nextSibling, _el$180 = _el$178.firstChild, _el$181 = _el$180.nextSibling;
8458
+ insert(_el$174, () => folder.name, _el$177);
8459
+ insert(_el$174, (() => {
8387
8460
  var _c$6 = memo(() => folder.items.length > 0);
8388
8461
  return () => _c$6() ? ` This folder has ${folder.items.length} bookmark${folder.items.length === 1 ? "" : "s"}.` : "";
8389
8462
  })(), null);
8390
- insert(_el$177, createComponent(Show, {
8463
+ insert(_el$178, createComponent(Show, {
8391
8464
  get when() {
8392
8465
  return folder.items.length > 0;
8393
8466
  },
8394
8467
  get children() {
8395
- var _el$178 = _tmpl$40();
8396
- _el$178.$$click = () => void handleRemoveFolder(folder.id, false);
8397
- return _el$178;
8468
+ var _el$179 = _tmpl$40();
8469
+ _el$179.$$click = () => void handleRemoveFolder(folder.id, false);
8470
+ return _el$179;
8398
8471
  }
8399
- }), _el$179);
8400
- _el$179.$$click = () => void handleRemoveFolder(folder.id, true);
8401
- insert(_el$179, () => folder.items.length > 0 ? "Delete all" : "Delete folder");
8402
- _el$180.$$click = () => setDeletingFolderId(null);
8403
- return _el$172;
8472
+ }), _el$180);
8473
+ _el$180.$$click = () => void handleRemoveFolder(folder.id, true);
8474
+ insert(_el$180, () => folder.items.length > 0 ? "Delete all" : "Delete folder");
8475
+ _el$181.$$click = () => setDeletingFolderId(null);
8476
+ return _el$173;
8404
8477
  }
8405
8478
  }), null);
8406
8479
  insert(_el$160, createComponent(Show, {
@@ -8408,19 +8481,19 @@ ${contextBlock}` : contextBlock);
8408
8481
  return editingFolderId() === folder.id;
8409
8482
  },
8410
8483
  get children() {
8411
- var _el$181 = _tmpl$42(), _el$182 = _el$181.firstChild, _el$183 = _el$182.firstChild, _el$184 = _el$183.nextSibling, _el$185 = _el$182.nextSibling, _el$186 = _el$185.nextSibling;
8412
- _el$183.$$input = (e) => setEditingFolderName(e.currentTarget.value);
8413
- _el$184.$$input = (e) => setEditingFolderSummary(e.currentTarget.value);
8414
- _el$185.$$click = () => void handleRenameFolder(folder.id);
8415
- _el$186.$$click = () => {
8484
+ var _el$182 = _tmpl$42(), _el$183 = _el$182.firstChild, _el$184 = _el$183.firstChild, _el$185 = _el$184.nextSibling, _el$186 = _el$183.nextSibling, _el$187 = _el$186.nextSibling;
8485
+ _el$184.$$input = (e) => setEditingFolderName(e.currentTarget.value);
8486
+ _el$185.$$input = (e) => setEditingFolderSummary(e.currentTarget.value);
8487
+ _el$186.$$click = () => void handleRenameFolder(folder.id);
8488
+ _el$187.$$click = () => {
8416
8489
  setEditingFolderId(null);
8417
8490
  setEditingFolderName("");
8418
8491
  setEditingFolderSummary("");
8419
8492
  };
8420
- createRenderEffect(() => _el$185.disabled = !editingFolderName().trim());
8421
- createRenderEffect(() => _el$183.value = editingFolderName());
8422
- createRenderEffect(() => _el$184.value = editingFolderSummary());
8423
- return _el$181;
8493
+ createRenderEffect(() => _el$186.disabled = !editingFolderName().trim());
8494
+ createRenderEffect(() => _el$184.value = editingFolderName());
8495
+ createRenderEffect(() => _el$185.value = editingFolderSummary());
8496
+ return _el$182;
8424
8497
  }
8425
8498
  }), null);
8426
8499
  insert(_el$160, createComponent(Show, {
@@ -8439,116 +8512,116 @@ ${contextBlock}` : contextBlock);
8439
8512
  return _tmpl$46();
8440
8513
  },
8441
8514
  get children() {
8442
- var _el$187 = _tmpl$43();
8443
- insert(_el$187, createComponent(For, {
8515
+ var _el$188 = _tmpl$43();
8516
+ insert(_el$188, createComponent(For, {
8444
8517
  get each() {
8445
8518
  return folder.items;
8446
8519
  },
8447
8520
  children: (bookmark) => (() => {
8448
- var _el$190 = _tmpl$53(), _el$191 = _el$190.firstChild, _el$192 = _el$191.firstChild, _el$193 = _el$192.nextSibling, _el$218 = _el$191.nextSibling, _el$219 = _el$218.firstChild, _el$220 = _el$219.nextSibling, _el$221 = _el$220.nextSibling;
8449
- _el$191.$$click = () => void createTab(bookmark.url);
8450
- insert(_el$192, () => bookmark.title || bookmark.url);
8451
- insert(_el$193, () => bookmark.url);
8452
- insert(_el$190, createComponent(Show, {
8521
+ var _el$191 = _tmpl$53(), _el$192 = _el$191.firstChild, _el$193 = _el$192.firstChild, _el$194 = _el$193.nextSibling, _el$219 = _el$192.nextSibling, _el$220 = _el$219.firstChild, _el$221 = _el$220.nextSibling, _el$222 = _el$221.nextSibling;
8522
+ _el$192.$$click = () => void createTab(bookmark.url);
8523
+ insert(_el$193, () => bookmark.title || bookmark.url);
8524
+ insert(_el$194, () => bookmark.url);
8525
+ insert(_el$191, createComponent(Show, {
8453
8526
  get when() {
8454
8527
  return bookmark.note;
8455
8528
  },
8456
8529
  get children() {
8457
- var _el$194 = _tmpl$47();
8458
- insert(_el$194, () => bookmark.note);
8459
- return _el$194;
8530
+ var _el$195 = _tmpl$47();
8531
+ insert(_el$195, () => bookmark.note);
8532
+ return _el$195;
8460
8533
  }
8461
- }), _el$218);
8462
- insert(_el$190, createComponent(Show, {
8534
+ }), _el$219);
8535
+ insert(_el$191, createComponent(Show, {
8463
8536
  get when() {
8464
8537
  return bookmark.intent || bookmark.expectedContent || (bookmark.keyFields?.length || 0) > 0 || (bookmark.agentHints && Object.keys(bookmark.agentHints).length || 0) > 0;
8465
8538
  },
8466
8539
  get children() {
8467
- var _el$195 = _tmpl$47();
8468
- insert(_el$195, createComponent(Show, {
8540
+ var _el$196 = _tmpl$47();
8541
+ insert(_el$196, createComponent(Show, {
8469
8542
  get when() {
8470
8543
  return bookmark.intent;
8471
8544
  },
8472
8545
  get children() {
8473
- var _el$196 = _tmpl$48(), _el$197 = _el$196.firstChild;
8474
- _el$197.nextSibling;
8475
- insert(_el$196, () => bookmark.intent, null);
8476
- return _el$196;
8546
+ var _el$197 = _tmpl$48(), _el$198 = _el$197.firstChild;
8547
+ _el$198.nextSibling;
8548
+ insert(_el$197, () => bookmark.intent, null);
8549
+ return _el$197;
8477
8550
  }
8478
8551
  }), null);
8479
- insert(_el$195, createComponent(Show, {
8552
+ insert(_el$196, createComponent(Show, {
8480
8553
  get when() {
8481
8554
  return bookmark.expectedContent;
8482
8555
  },
8483
8556
  get children() {
8484
- var _el$199 = _tmpl$49(), _el$200 = _el$199.firstChild;
8485
- _el$200.nextSibling;
8486
- insert(_el$199, () => bookmark.expectedContent, null);
8487
- return _el$199;
8557
+ var _el$200 = _tmpl$49(), _el$201 = _el$200.firstChild;
8558
+ _el$201.nextSibling;
8559
+ insert(_el$200, () => bookmark.expectedContent, null);
8560
+ return _el$200;
8488
8561
  }
8489
8562
  }), null);
8490
- insert(_el$195, createComponent(Show, {
8563
+ insert(_el$196, createComponent(Show, {
8491
8564
  get when() {
8492
8565
  return (bookmark.keyFields?.length || 0) > 0;
8493
8566
  },
8494
8567
  get children() {
8495
- var _el$202 = _tmpl$50(), _el$203 = _el$202.firstChild;
8496
- _el$203.nextSibling;
8497
- insert(_el$202, () => bookmark.keyFields?.join(", "), null);
8498
- return _el$202;
8568
+ var _el$203 = _tmpl$50(), _el$204 = _el$203.firstChild;
8569
+ _el$204.nextSibling;
8570
+ insert(_el$203, () => bookmark.keyFields?.join(", "), null);
8571
+ return _el$203;
8499
8572
  }
8500
8573
  }), null);
8501
- insert(_el$195, createComponent(Show, {
8574
+ insert(_el$196, createComponent(Show, {
8502
8575
  get when() {
8503
8576
  return memo(() => !!bookmark.agentHints)() && Object.keys(bookmark.agentHints).length > 0;
8504
8577
  },
8505
8578
  get children() {
8506
- var _el$205 = _tmpl$51(), _el$206 = _el$205.firstChild;
8507
- _el$206.nextSibling;
8508
- insert(_el$205, () => Object.entries(bookmark.agentHints || {}).map(([key, hint]) => `${key}: ${hint}`).join(" • "), null);
8509
- return _el$205;
8579
+ var _el$206 = _tmpl$51(), _el$207 = _el$206.firstChild;
8580
+ _el$207.nextSibling;
8581
+ insert(_el$206, () => Object.entries(bookmark.agentHints || {}).map(([key, hint]) => `${key}: ${hint}`).join(" • "), null);
8582
+ return _el$206;
8510
8583
  }
8511
8584
  }), null);
8512
- return _el$195;
8585
+ return _el$196;
8513
8586
  }
8514
- }), _el$218);
8515
- insert(_el$190, createComponent(Show, {
8587
+ }), _el$219);
8588
+ insert(_el$191, createComponent(Show, {
8516
8589
  get when() {
8517
8590
  return editingBookmarkId() === bookmark.id;
8518
8591
  },
8519
8592
  get children() {
8520
- var _el$208 = _tmpl$52(), _el$209 = _el$208.firstChild, _el$210 = _el$209.nextSibling, _el$211 = _el$210.nextSibling, _el$212 = _el$211.nextSibling, _el$213 = _el$212.nextSibling, _el$214 = _el$213.nextSibling, _el$215 = _el$214.nextSibling, _el$216 = _el$215.firstChild, _el$217 = _el$216.nextSibling;
8521
- _el$209.$$input = (e) => setEditingBookmarkTitle(e.currentTarget.value);
8522
- _el$210.$$input = (e) => setEditingBookmarkNote(e.currentTarget.value);
8523
- _el$211.$$input = (e) => setEditingBookmarkIntent(e.currentTarget.value);
8524
- _el$212.$$input = (e) => setEditingBookmarkExpectedContent(e.currentTarget.value);
8525
- _el$213.$$input = (e) => setEditingBookmarkKeyFields(e.currentTarget.value);
8526
- _el$214.$$input = (e) => setEditingBookmarkAgentHints(e.currentTarget.value);
8527
- _el$216.$$click = () => void handleUpdateBookmark(bookmark.id);
8528
- _el$217.$$click = resetBookmarkEditor;
8529
- createRenderEffect(() => _el$209.value = editingBookmarkTitle());
8530
- createRenderEffect(() => _el$210.value = editingBookmarkNote());
8531
- createRenderEffect(() => _el$211.value = editingBookmarkIntent());
8532
- createRenderEffect(() => _el$212.value = editingBookmarkExpectedContent());
8533
- createRenderEffect(() => _el$213.value = editingBookmarkKeyFields());
8534
- createRenderEffect(() => _el$214.value = editingBookmarkAgentHints());
8535
- return _el$208;
8593
+ var _el$209 = _tmpl$52(), _el$210 = _el$209.firstChild, _el$211 = _el$210.nextSibling, _el$212 = _el$211.nextSibling, _el$213 = _el$212.nextSibling, _el$214 = _el$213.nextSibling, _el$215 = _el$214.nextSibling, _el$216 = _el$215.nextSibling, _el$217 = _el$216.firstChild, _el$218 = _el$217.nextSibling;
8594
+ _el$210.$$input = (e) => setEditingBookmarkTitle(e.currentTarget.value);
8595
+ _el$211.$$input = (e) => setEditingBookmarkNote(e.currentTarget.value);
8596
+ _el$212.$$input = (e) => setEditingBookmarkIntent(e.currentTarget.value);
8597
+ _el$213.$$input = (e) => setEditingBookmarkExpectedContent(e.currentTarget.value);
8598
+ _el$214.$$input = (e) => setEditingBookmarkKeyFields(e.currentTarget.value);
8599
+ _el$215.$$input = (e) => setEditingBookmarkAgentHints(e.currentTarget.value);
8600
+ _el$217.$$click = () => void handleUpdateBookmark(bookmark.id);
8601
+ _el$218.$$click = resetBookmarkEditor;
8602
+ createRenderEffect(() => _el$210.value = editingBookmarkTitle());
8603
+ createRenderEffect(() => _el$211.value = editingBookmarkNote());
8604
+ createRenderEffect(() => _el$212.value = editingBookmarkIntent());
8605
+ createRenderEffect(() => _el$213.value = editingBookmarkExpectedContent());
8606
+ createRenderEffect(() => _el$214.value = editingBookmarkKeyFields());
8607
+ createRenderEffect(() => _el$215.value = editingBookmarkAgentHints());
8608
+ return _el$209;
8536
8609
  }
8537
- }), _el$218);
8538
- insert(_el$219, () => formatBookmarkDate(bookmark.savedAt));
8539
- _el$220.$$click = () => editingBookmarkId() === bookmark.id ? resetBookmarkEditor() : startEditingBookmark(bookmark);
8540
- insert(_el$220, () => editingBookmarkId() === bookmark.id ? "Close" : "Edit");
8541
- _el$221.$$click = () => {
8610
+ }), _el$219);
8611
+ insert(_el$220, () => formatBookmarkDate(bookmark.savedAt));
8612
+ _el$221.$$click = () => editingBookmarkId() === bookmark.id ? resetBookmarkEditor() : startEditingBookmark(bookmark);
8613
+ insert(_el$221, () => editingBookmarkId() === bookmark.id ? "Close" : "Edit");
8614
+ _el$222.$$click = () => {
8542
8615
  if (editingBookmarkId() === bookmark.id) {
8543
8616
  resetBookmarkEditor();
8544
8617
  }
8545
8618
  void removeBookmark(bookmark.id);
8546
8619
  };
8547
- createRenderEffect(() => setAttribute(_el$190, "data-bookmark-id", bookmark.id));
8548
- return _el$190;
8620
+ createRenderEffect(() => setAttribute(_el$191, "data-bookmark-id", bookmark.id));
8621
+ return _el$191;
8549
8622
  })()
8550
8623
  }));
8551
- return _el$187;
8624
+ return _el$188;
8552
8625
  }
8553
8626
  });
8554
8627
  }
@@ -8615,8 +8688,8 @@ ${contextBlock}` : contextBlock);
8615
8688
  return recentCheckpoints();
8616
8689
  },
8617
8690
  children: (checkpoint, i) => (() => {
8618
- var _el$223 = _tmpl$56(), _el$224 = _el$223.firstChild, _el$225 = _el$224.firstChild, _el$227 = _el$224.nextSibling, _el$228 = _el$227.firstChild, _el$229 = _el$228.nextSibling, _el$230 = _el$229.nextSibling, _el$231 = _el$230.nextSibling;
8619
- insert(_el$224, createComponent(Show, {
8691
+ var _el$224 = _tmpl$56(), _el$225 = _el$224.firstChild, _el$226 = _el$225.firstChild, _el$228 = _el$225.nextSibling, _el$229 = _el$228.firstChild, _el$230 = _el$229.nextSibling, _el$231 = _el$230.nextSibling, _el$232 = _el$231.nextSibling;
8692
+ insert(_el$225, createComponent(Show, {
8620
8693
  get when() {
8621
8694
  return i() < recentCheckpoints().length - 1;
8622
8695
  },
@@ -8624,13 +8697,13 @@ ${contextBlock}` : contextBlock);
8624
8697
  return _tmpl$55();
8625
8698
  }
8626
8699
  }), null);
8627
- insert(_el$228, () => checkpoint.name);
8628
- insert(_el$229, () => new Date(checkpoint.createdAt).toLocaleString());
8629
- _el$230.addEventListener("blur", (e) => void updateCheckpointNote(checkpoint.id, e.currentTarget.value));
8630
- _el$231.$$click = () => void restoreCheckpoint(checkpoint.id);
8631
- createRenderEffect(() => _el$225.classList.toggle("latest", !!(i() === 0)));
8632
- createRenderEffect(() => _el$230.value = checkpoint.note || "");
8633
- return _el$223;
8700
+ insert(_el$229, () => checkpoint.name);
8701
+ insert(_el$230, () => new Date(checkpoint.createdAt).toLocaleString());
8702
+ _el$231.addEventListener("blur", (e) => void updateCheckpointNote(checkpoint.id, e.currentTarget.value));
8703
+ _el$232.$$click = () => void restoreCheckpoint(checkpoint.id);
8704
+ createRenderEffect(() => _el$226.classList.toggle("latest", !!(i() === 0)));
8705
+ createRenderEffect(() => _el$231.value = checkpoint.note || "");
8706
+ return _el$224;
8634
8707
  })()
8635
8708
  }));
8636
8709
  return _el$95;
@@ -8677,12 +8750,12 @@ ${contextBlock}` : contextBlock);
8677
8750
  return history.historyState().entries;
8678
8751
  },
8679
8752
  children: (entry) => (() => {
8680
- var _el$232 = _tmpl$57(), _el$233 = _el$232.firstChild, _el$234 = _el$233.nextSibling, _el$235 = _el$234.nextSibling;
8681
- _el$232.$$click = () => createTab(entry.url);
8682
- insert(_el$233, () => entry.title || entry.url);
8683
- insert(_el$234, () => entry.url);
8684
- insert(_el$235, () => new Date(entry.visitedAt).toLocaleString());
8685
- return _el$232;
8753
+ var _el$233 = _tmpl$57(), _el$234 = _el$233.firstChild, _el$235 = _el$234.nextSibling, _el$236 = _el$235.nextSibling;
8754
+ _el$233.$$click = () => createTab(entry.url);
8755
+ insert(_el$234, () => entry.title || entry.url);
8756
+ insert(_el$235, () => entry.url);
8757
+ insert(_el$236, () => new Date(entry.visitedAt).toLocaleString());
8758
+ return _el$233;
8686
8759
  })()
8687
8760
  }), null);
8688
8761
  insert(_el$104, createComponent(Show, {
@@ -8709,11 +8782,11 @@ ${contextBlock}` : contextBlock);
8709
8782
  },
8710
8783
  get fallback() {
8711
8784
  return (() => {
8712
- var _el$236 = _tmpl$58(), _el$237 = _el$236.firstChild, _el$238 = _el$237.nextSibling, _el$239 = _el$238.nextSibling, _el$240 = _el$239.firstChild, _el$241 = _el$240.nextSibling;
8713
- _el$240.$$click = () => void window.vessel.premium.checkout(premiumState().email || void 0).catch(() => {
8785
+ var _el$237 = _tmpl$58(), _el$238 = _el$237.firstChild, _el$239 = _el$238.nextSibling, _el$240 = _el$239.nextSibling, _el$241 = _el$240.firstChild, _el$242 = _el$241.nextSibling;
8786
+ _el$241.$$click = () => void window.vessel.premium.checkout(premiumState().email || void 0).catch(() => {
8714
8787
  });
8715
- _el$241.$$click = openPremiumDetails;
8716
- return _el$236;
8788
+ _el$242.$$click = openPremiumDetails;
8789
+ return _el$237;
8717
8790
  })();
8718
8791
  },
8719
8792
  get children() {
@@ -8743,13 +8816,13 @@ ${contextBlock}` : contextBlock);
8743
8816
  return messages2();
8744
8817
  },
8745
8818
  children: (msg) => (() => {
8746
- var _el$242 = _tmpl$59();
8747
- insert(_el$242, createComponent(MarkdownMessage, {
8819
+ var _el$243 = _tmpl$59();
8820
+ insert(_el$243, createComponent(MarkdownMessage, {
8748
8821
  get content() {
8749
8822
  return msg.content;
8750
8823
  }
8751
8824
  }), null);
8752
- insert(_el$242, createComponent(Show, {
8825
+ insert(_el$243, createComponent(Show, {
8753
8826
  get when() {
8754
8827
  return memo(() => msg.role === "assistant")() ? getPremiumPromptKind(msg.content) : null;
8755
8828
  },
@@ -8762,8 +8835,8 @@ ${contextBlock}` : contextBlock);
8762
8835
  onOpenSettings: openPremiumDetails
8763
8836
  })
8764
8837
  }), null);
8765
- createRenderEffect(() => className(_el$242, `message message-${msg.role}`));
8766
- return _el$242;
8838
+ createRenderEffect(() => className(_el$243, `message message-${msg.role}`));
8839
+ return _el$243;
8767
8840
  })()
8768
8841
  }), createComponent(Show, {
8769
8842
  get when() {
@@ -8824,22 +8897,22 @@ ${contextBlock}` : contextBlock);
8824
8897
  return runtimeState2().supervisor.pendingApprovals;
8825
8898
  },
8826
8899
  children: (approval) => (() => {
8827
- var _el$244 = _tmpl$62(), _el$245 = _el$244.firstChild, _el$246 = _el$245.nextSibling, _el$247 = _el$246.firstChild, _el$248 = _el$247.firstChild, _el$249 = _el$248.nextSibling, _el$251 = _el$247.nextSibling, _el$252 = _el$251.nextSibling, _el$253 = _el$252.firstChild, _el$254 = _el$253.nextSibling;
8828
- insert(_el$249, () => approval.name);
8829
- insert(_el$246, createComponent(Show, {
8900
+ var _el$245 = _tmpl$62(), _el$246 = _el$245.firstChild, _el$247 = _el$246.nextSibling, _el$248 = _el$247.firstChild, _el$249 = _el$248.firstChild, _el$250 = _el$249.nextSibling, _el$252 = _el$248.nextSibling, _el$253 = _el$252.nextSibling, _el$254 = _el$253.firstChild, _el$255 = _el$254.nextSibling;
8901
+ insert(_el$250, () => approval.name);
8902
+ insert(_el$247, createComponent(Show, {
8830
8903
  get when() {
8831
8904
  return approval.argsSummary;
8832
8905
  },
8833
8906
  get children() {
8834
- var _el$250 = _tmpl$61();
8835
- insert(_el$250, () => approval.argsSummary);
8836
- return _el$250;
8907
+ var _el$251 = _tmpl$61();
8908
+ insert(_el$251, () => approval.argsSummary);
8909
+ return _el$251;
8837
8910
  }
8838
- }), _el$251);
8839
- insert(_el$251, () => approval.reason);
8840
- _el$253.$$click = () => void resolveApproval(approval.id, true);
8841
- _el$254.$$click = () => void resolveApproval(approval.id, false);
8842
- return _el$244;
8911
+ }), _el$252);
8912
+ insert(_el$252, () => approval.reason);
8913
+ _el$254.$$click = () => void resolveApproval(approval.id, true);
8914
+ _el$255.$$click = () => void resolveApproval(approval.id, false);
8915
+ return _el$245;
8843
8916
  })()
8844
8917
  });
8845
8918
  }
@@ -8942,12 +9015,12 @@ ${contextBlock}` : contextBlock);
8942
9015
  return pendingQueries2();
8943
9016
  },
8944
9017
  children: (pendingPrompt, index) => (() => {
8945
- var _el$255 = _tmpl$63(), _el$256 = _el$255.firstChild, _el$257 = _el$256.nextSibling;
8946
- setAttribute(_el$256, "title", pendingPrompt);
8947
- insert(_el$256, pendingPrompt);
8948
- _el$257.$$click = () => removePendingQuery(index());
8949
- createRenderEffect(() => setAttribute(_el$257, "aria-label", `Remove queued prompt ${index() + 1}`));
8950
- return _el$255;
9018
+ var _el$256 = _tmpl$63(), _el$257 = _el$256.firstChild, _el$258 = _el$257.nextSibling;
9019
+ setAttribute(_el$257, "title", pendingPrompt);
9020
+ insert(_el$257, pendingPrompt);
9021
+ _el$258.$$click = () => removePendingQuery(index());
9022
+ createRenderEffect(() => setAttribute(_el$258, "aria-label", `Remove queued prompt ${index() + 1}`));
9023
+ return _el$256;
8951
9024
  })()
8952
9025
  }));
8953
9026
  return _el$137;
@@ -5,7 +5,7 @@
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-Dhg4KPX1.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-DM2iGE8-.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="./assets/index-CHSGQlQr.css">
10
10
  </head>
11
11
  <body>
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.80",
4
+ "version": "0.1.83",
5
5
  "description": "AI-native web browser runtime for autonomous agents with human supervision",
6
6
  "main": "./out/main/index.js",
7
7
  "bin": {