@quanta-intellect/vessel-browser 0.1.90 → 0.1.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/out/main/index.js CHANGED
@@ -117,15 +117,15 @@ function readStoredProviderSecret() {
117
117
  return null;
118
118
  }
119
119
  function writeStoredProviderSecret(secret) {
120
- const filePath = getChatProviderSecretPath();
121
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
120
+ const filePath2 = getChatProviderSecretPath();
121
+ fs.mkdirSync(path.dirname(filePath2), { recursive: true });
122
122
  const payload = JSON.stringify(secret);
123
123
  if (canUseSafeStorage$1()) {
124
124
  const encrypted = electron.safeStorage.encryptString(payload);
125
- fs.writeFileSync(filePath, encrypted, { mode: 384 });
125
+ fs.writeFileSync(filePath2, encrypted, { mode: 384 });
126
126
  return;
127
127
  }
128
- fs.writeFileSync(filePath, payload, { mode: 384 });
128
+ fs.writeFileSync(filePath2, payload, { mode: 384 });
129
129
  }
130
130
  function clearStoredProviderSecret() {
131
131
  try {
@@ -149,15 +149,15 @@ function readStoredCodexTokens() {
149
149
  return null;
150
150
  }
151
151
  function writeStoredCodexTokens(tokens) {
152
- const filePath = getCodexTokensPath();
153
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
152
+ const filePath2 = getCodexTokensPath();
153
+ fs.mkdirSync(path.dirname(filePath2), { recursive: true });
154
154
  const payload = JSON.stringify(tokens);
155
155
  if (canUseSafeStorage$1()) {
156
156
  const encrypted = electron.safeStorage.encryptString(payload);
157
- fs.writeFileSync(filePath, encrypted, { mode: 384 });
157
+ fs.writeFileSync(filePath2, encrypted, { mode: 384 });
158
158
  return;
159
159
  }
160
- fs.writeFileSync(filePath, payload, { mode: 384 });
160
+ fs.writeFileSync(filePath2, payload, { mode: 384 });
161
161
  }
162
162
  function clearStoredCodexTokens() {
163
163
  try {
@@ -282,11 +282,11 @@ function saveSettings() {
282
282
  }
283
283
  }, SAVE_DEBOUNCE_MS$6);
284
284
  }
285
- function setSetting(key, value) {
285
+ function setSetting(key2, value) {
286
286
  loadSettings();
287
- if (key === "mcpPort") {
287
+ if (key2 === "mcpPort") {
288
288
  settings.mcpPort = sanitizePort(value);
289
- } else if (key === "chatProvider") {
289
+ } else if (key2 === "chatProvider") {
290
290
  const nextProvider = value;
291
291
  if (!nextProvider) {
292
292
  clearStoredProviderSecret();
@@ -314,7 +314,7 @@ function setSetting(key, value) {
314
314
  };
315
315
  }
316
316
  } else {
317
- settings[key] = value;
317
+ settings[key2] = value;
318
318
  }
319
319
  saveSettings();
320
320
  return { ...settings };
@@ -490,27 +490,27 @@ class Tab {
490
490
  this.view.webContents.on("before-input-event", (event, input) => {
491
491
  if (!input.control && !input.meta) return;
492
492
  if (input.type !== "keyDown") return;
493
- const key = input.key.toLowerCase();
493
+ const key2 = input.key.toLowerCase();
494
494
  const wc = this.view.webContents;
495
- if (key === "+" || key === "=") {
495
+ if (key2 === "+" || key2 === "=") {
496
496
  this.zoomIn();
497
497
  event.preventDefault();
498
498
  return;
499
499
  }
500
- if (key === "-") {
500
+ if (key2 === "-") {
501
501
  this.zoomOut();
502
502
  event.preventDefault();
503
503
  return;
504
504
  }
505
- if (key === "0") {
505
+ if (key2 === "0") {
506
506
  this.zoomReset();
507
507
  event.preventDefault();
508
508
  return;
509
509
  }
510
- if (key === "c") wc.copy();
511
- else if (key === "v") wc.paste();
512
- else if (key === "x") wc.cut();
513
- else if (key === "a") wc.selectAll();
510
+ if (key2 === "c") wc.copy();
511
+ else if (key2 === "v") wc.paste();
512
+ else if (key2 === "x") wc.cut();
513
+ else if (key2 === "a") wc.selectAll();
514
514
  });
515
515
  this.setupListeners();
516
516
  if (url) {
@@ -784,8 +784,8 @@ class Tab {
784
784
  }
785
785
  if (postBody) {
786
786
  const params = new URLSearchParams();
787
- for (const [key, value] of Object.entries(postBody)) {
788
- params.set(key, value);
787
+ for (const [key2, value] of Object.entries(postBody)) {
788
+ params.set(key2, value);
789
789
  }
790
790
  return this.guardedLoadURL(url, {
791
791
  method: "POST",
@@ -1059,22 +1059,22 @@ function encodeStoredData(payload, secure) {
1059
1059
  return payload;
1060
1060
  }
1061
1061
  function loadJsonFile({
1062
- filePath,
1062
+ filePath: filePath2,
1063
1063
  fallback,
1064
- parse,
1064
+ parse: parse2,
1065
1065
  secure = false
1066
1066
  }) {
1067
1067
  try {
1068
- const raw = fs.readFileSync(filePath);
1068
+ const raw = fs.readFileSync(filePath2);
1069
1069
  const decoded = decodeStoredData(raw, secure);
1070
- return parse(JSON.parse(decoded));
1070
+ return parse2(JSON.parse(decoded));
1071
1071
  } catch {
1072
1072
  return fallback;
1073
1073
  }
1074
1074
  }
1075
1075
  function createDebouncedJsonPersistence({
1076
1076
  debounceMs,
1077
- filePath,
1077
+ filePath: filePath2,
1078
1078
  getValue,
1079
1079
  logLabel,
1080
1080
  resetOnSchedule = false,
@@ -1097,9 +1097,9 @@ function createDebouncedJsonPersistence({
1097
1097
  2
1098
1098
  );
1099
1099
  const data = encodeStoredData(payload, secure);
1100
- await fs.promises.mkdir(path.dirname(filePath), { recursive: true }).then(
1100
+ await fs.promises.mkdir(path.dirname(filePath2), { recursive: true }).then(
1101
1101
  () => fs.promises.writeFile(
1102
- filePath,
1102
+ filePath2,
1103
1103
  data,
1104
1104
  typeof data === "string" ? { encoding: "utf-8", mode: 384 } : { mode: 384 }
1105
1105
  )
@@ -1125,7 +1125,7 @@ function createDebouncedJsonPersistence({
1125
1125
  flush: flush2
1126
1126
  };
1127
1127
  }
1128
- let state$4 = null;
1128
+ let state$5 = null;
1129
1129
  const listeners$2 = /* @__PURE__ */ new Set();
1130
1130
  const SAVE_DEBOUNCE_MS$5 = 250;
1131
1131
  function getHighlightsPath() {
@@ -1135,19 +1135,19 @@ function createPersistence$1() {
1135
1135
  return createDebouncedJsonPersistence({
1136
1136
  debounceMs: SAVE_DEBOUNCE_MS$5,
1137
1137
  filePath: getHighlightsPath(),
1138
- getValue: () => state$4,
1138
+ getValue: () => state$5,
1139
1139
  logLabel: "highlights",
1140
1140
  resetOnSchedule: true
1141
1141
  });
1142
1142
  }
1143
- let persistence$5 = null;
1143
+ let persistence$7 = null;
1144
1144
  function getPersistence$1() {
1145
- persistence$5 ??= createPersistence$1();
1146
- return persistence$5;
1145
+ persistence$7 ??= createPersistence$1();
1146
+ return persistence$7;
1147
1147
  }
1148
1148
  function load$4() {
1149
- if (state$4) return state$4;
1150
- state$4 = loadJsonFile({
1149
+ if (state$5) return state$5;
1150
+ state$5 = loadJsonFile({
1151
1151
  filePath: getHighlightsPath(),
1152
1152
  fallback: { highlights: [] },
1153
1153
  parse: (raw) => {
@@ -1157,14 +1157,14 @@ function load$4() {
1157
1157
  };
1158
1158
  }
1159
1159
  });
1160
- return state$4;
1160
+ return state$5;
1161
1161
  }
1162
- function save$2() {
1162
+ function save$3() {
1163
1163
  getPersistence$1().schedule();
1164
1164
  }
1165
- function emit$2() {
1166
- if (!state$4) return;
1167
- const snapshot = { highlights: [...state$4.highlights] };
1165
+ function emit$4() {
1166
+ if (!state$5) return;
1167
+ const snapshot = { highlights: [...state$5.highlights] };
1168
1168
  for (const listener of listeners$2) {
1169
1169
  listener(snapshot);
1170
1170
  }
@@ -1180,12 +1180,12 @@ function normalizeUrl$1(rawUrl) {
1180
1180
  }
1181
1181
  function getState$2() {
1182
1182
  load$4();
1183
- return { highlights: [...state$4.highlights] };
1183
+ return { highlights: [...state$5.highlights] };
1184
1184
  }
1185
1185
  function getHighlightsForUrl(url) {
1186
1186
  load$4();
1187
1187
  const normalized = normalizeUrl$1(url);
1188
- return state$4.highlights.filter((h) => h.url === normalized);
1188
+ return state$5.highlights.filter((h) => h.url === normalized);
1189
1189
  }
1190
1190
  function addHighlight(url, selector, text, label, color, source) {
1191
1191
  load$4();
@@ -1199,45 +1199,45 @@ function addHighlight(url, selector, text, label, color, source) {
1199
1199
  source: source || void 0,
1200
1200
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
1201
1201
  };
1202
- state$4.highlights.push(highlight);
1203
- save$2();
1204
- emit$2();
1202
+ state$5.highlights.push(highlight);
1203
+ save$3();
1204
+ emit$4();
1205
1205
  return highlight;
1206
1206
  }
1207
1207
  function removeHighlight(id) {
1208
1208
  load$4();
1209
- const index = state$4.highlights.findIndex((h) => h.id === id);
1209
+ const index = state$5.highlights.findIndex((h) => h.id === id);
1210
1210
  if (index === -1) return null;
1211
- const [removed] = state$4.highlights.splice(index, 1);
1212
- save$2();
1213
- emit$2();
1211
+ const [removed] = state$5.highlights.splice(index, 1);
1212
+ save$3();
1213
+ emit$4();
1214
1214
  return removed;
1215
1215
  }
1216
1216
  function findHighlightByText(url, text) {
1217
1217
  load$4();
1218
1218
  const normalized = normalizeUrl$1(url);
1219
- return state$4.highlights.find(
1219
+ return state$5.highlights.find(
1220
1220
  (h) => h.url === normalized && h.text && h.text === text
1221
1221
  ) ?? null;
1222
1222
  }
1223
1223
  function updateHighlightColor(id, color) {
1224
1224
  load$4();
1225
- const highlight = state$4.highlights.find((h) => h.id === id);
1225
+ const highlight = state$5.highlights.find((h) => h.id === id);
1226
1226
  if (!highlight) return null;
1227
1227
  highlight.color = color;
1228
- save$2();
1229
- emit$2();
1228
+ save$3();
1229
+ emit$4();
1230
1230
  return highlight;
1231
1231
  }
1232
1232
  function clearHighlightsForUrl(url) {
1233
1233
  load$4();
1234
1234
  const normalized = normalizeUrl$1(url);
1235
- const before = state$4.highlights.length;
1236
- state$4.highlights = state$4.highlights.filter((h) => h.url !== normalized);
1237
- const removed = before - state$4.highlights.length;
1235
+ const before = state$5.highlights.length;
1236
+ state$5.highlights = state$5.highlights.filter((h) => h.url !== normalized);
1237
+ const removed = before - state$5.highlights.length;
1238
1238
  if (removed > 0) {
1239
- save$2();
1240
- emit$2();
1239
+ save$3();
1240
+ emit$4();
1241
1241
  }
1242
1242
  return removed;
1243
1243
  }
@@ -1867,14 +1867,14 @@ function persistHighlight(url, text) {
1867
1867
  }
1868
1868
  const MAX_HISTORY_ENTRIES = 5e3;
1869
1869
  const SAVE_DEBOUNCE_MS$4 = 250;
1870
- let state$3 = null;
1870
+ let state$4 = null;
1871
1871
  const listeners$1 = /* @__PURE__ */ new Set();
1872
1872
  function getHistoryPath() {
1873
1873
  return path.join(electron.app.getPath("userData"), "vessel-history.json");
1874
1874
  }
1875
1875
  function load$3() {
1876
- if (state$3) return state$3;
1877
- state$3 = loadJsonFile({
1876
+ if (state$4) return state$4;
1877
+ state$4 = loadJsonFile({
1878
1878
  filePath: getHistoryPath(),
1879
1879
  fallback: { entries: [] },
1880
1880
  parse: (raw) => {
@@ -1884,27 +1884,27 @@ function load$3() {
1884
1884
  };
1885
1885
  }
1886
1886
  });
1887
- return state$3;
1887
+ return state$4;
1888
1888
  }
1889
- const persistence$4 = createDebouncedJsonPersistence({
1889
+ const persistence$6 = createDebouncedJsonPersistence({
1890
1890
  debounceMs: SAVE_DEBOUNCE_MS$4,
1891
1891
  filePath: getHistoryPath(),
1892
- getValue: () => state$3,
1892
+ getValue: () => state$4,
1893
1893
  logLabel: "history"
1894
1894
  });
1895
- function save$1() {
1896
- persistence$4.schedule();
1895
+ function save$2() {
1896
+ persistence$6.schedule();
1897
1897
  }
1898
- function emit$1() {
1899
- if (!state$3) return;
1900
- const snapshot = { entries: [...state$3.entries] };
1898
+ function emit$3() {
1899
+ if (!state$4) return;
1900
+ const snapshot = { entries: [...state$4.entries] };
1901
1901
  for (const listener of listeners$1) {
1902
1902
  listener(snapshot);
1903
1903
  }
1904
1904
  }
1905
1905
  function getState$1() {
1906
1906
  load$3();
1907
- return { entries: [...state$3.entries] };
1907
+ return { entries: [...state$4.entries] };
1908
1908
  }
1909
1909
  function subscribe$1(listener) {
1910
1910
  listeners$1.add(listener);
@@ -1915,12 +1915,12 @@ function subscribe$1(listener) {
1915
1915
  function addEntry$1(url, title) {
1916
1916
  if (!url || url === "about:blank") return;
1917
1917
  load$3();
1918
- const last = state$3.entries[0];
1918
+ const last = state$4.entries[0];
1919
1919
  if (last && last.url === url) {
1920
1920
  if (title && title !== last.title) {
1921
1921
  last.title = title;
1922
- save$1();
1923
- emit$1();
1922
+ save$2();
1923
+ emit$3();
1924
1924
  }
1925
1925
  return;
1926
1926
  }
@@ -1929,25 +1929,25 @@ function addEntry$1(url, title) {
1929
1929
  title: title || url,
1930
1930
  visitedAt: (/* @__PURE__ */ new Date()).toISOString()
1931
1931
  };
1932
- state$3.entries.unshift(entry);
1933
- if (state$3.entries.length > MAX_HISTORY_ENTRIES) {
1934
- state$3.entries = state$3.entries.slice(0, MAX_HISTORY_ENTRIES);
1932
+ state$4.entries.unshift(entry);
1933
+ if (state$4.entries.length > MAX_HISTORY_ENTRIES) {
1934
+ state$4.entries = state$4.entries.slice(0, MAX_HISTORY_ENTRIES);
1935
1935
  }
1936
- save$1();
1937
- emit$1();
1936
+ save$2();
1937
+ emit$3();
1938
1938
  }
1939
1939
  function search(query, limit = 50) {
1940
1940
  load$3();
1941
- if (!query.trim()) return state$3.entries.slice(0, limit);
1941
+ if (!query.trim()) return state$4.entries.slice(0, limit);
1942
1942
  const normalized = query.toLowerCase();
1943
- return state$3.entries.filter(
1943
+ return state$4.entries.filter(
1944
1944
  (e) => e.url.toLowerCase().includes(normalized) || e.title.toLowerCase().includes(normalized)
1945
1945
  ).slice(0, limit);
1946
1946
  }
1947
1947
  function clearAll$1() {
1948
- state$3 = { entries: [] };
1949
- save$1();
1950
- emit$1();
1948
+ state$4 = { entries: [] };
1949
+ save$2();
1950
+ emit$3();
1951
1951
  }
1952
1952
  function clearByTimeRange(timeRange) {
1953
1953
  load$3();
@@ -1957,12 +1957,12 @@ function clearByTimeRange(timeRange) {
1957
1957
  }
1958
1958
  const now = Date.now();
1959
1959
  const cutoff = new Date(now - timeRangeToMs(timeRange));
1960
- state$3.entries = state$3.entries.filter((entry) => {
1960
+ state$4.entries = state$4.entries.filter((entry) => {
1961
1961
  const visitedAt = new Date(entry.visitedAt).getTime();
1962
1962
  return Number.isNaN(visitedAt) || visitedAt < cutoff.getTime();
1963
1963
  });
1964
- save$1();
1965
- emit$1();
1964
+ save$2();
1965
+ emit$3();
1966
1966
  }
1967
1967
  function timeRangeToMs(range) {
1968
1968
  switch (range) {
@@ -2016,7 +2016,7 @@ function importHistoryFromJson(content) {
2016
2016
  const parsed = JSON.parse(content);
2017
2017
  const entries = Array.isArray(parsed?.entries) ? parsed.entries : [];
2018
2018
  load$3();
2019
- const existingUrls = new Set(state$3.entries.map((e) => e.url));
2019
+ const existingUrls = new Set(state$4.entries.map((e) => e.url));
2020
2020
  for (const entry of entries) {
2021
2021
  if (!entry?.url || typeof entry.url !== "string") {
2022
2022
  errors++;
@@ -2026,7 +2026,7 @@ function importHistoryFromJson(content) {
2026
2026
  skipped++;
2027
2027
  continue;
2028
2028
  }
2029
- state$3.entries.push({
2029
+ state$4.entries.push({
2030
2030
  url: entry.url,
2031
2031
  title: typeof entry.title === "string" ? entry.title : entry.url,
2032
2032
  visitedAt: typeof entry.visitedAt === "string" ? entry.visitedAt : (/* @__PURE__ */ new Date()).toISOString()
@@ -2034,14 +2034,14 @@ function importHistoryFromJson(content) {
2034
2034
  existingUrls.add(entry.url);
2035
2035
  imported++;
2036
2036
  }
2037
- state$3.entries.sort(
2037
+ state$4.entries.sort(
2038
2038
  (a, b) => new Date(b.visitedAt).getTime() - new Date(a.visitedAt).getTime()
2039
2039
  );
2040
- if (state$3.entries.length > MAX_HISTORY_ENTRIES) {
2041
- state$3.entries = state$3.entries.slice(0, MAX_HISTORY_ENTRIES);
2040
+ if (state$4.entries.length > MAX_HISTORY_ENTRIES) {
2041
+ state$4.entries = state$4.entries.slice(0, MAX_HISTORY_ENTRIES);
2042
2042
  }
2043
- save$1();
2044
- emit$1();
2043
+ save$2();
2044
+ emit$3();
2045
2045
  } catch {
2046
2046
  errors++;
2047
2047
  }
@@ -2052,7 +2052,7 @@ function importHistoryFromHtml(content) {
2052
2052
  let skipped = 0;
2053
2053
  let errors = 0;
2054
2054
  load$3();
2055
- const existingUrls = new Set(state$3.entries.map((e) => e.url));
2055
+ const existingUrls = new Set(state$4.entries.map((e) => e.url));
2056
2056
  const hrefRegex = /<A\s+[^>]*HREF="([^"]+)"[^>]*>([^<]*)<\/A>/gi;
2057
2057
  let match;
2058
2058
  while ((match = hrefRegex.exec(content)) !== null) {
@@ -2063,7 +2063,7 @@ function importHistoryFromHtml(content) {
2063
2063
  else errors++;
2064
2064
  continue;
2065
2065
  }
2066
- state$3.entries.push({
2066
+ state$4.entries.push({
2067
2067
  url,
2068
2068
  title,
2069
2069
  visitedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -2071,18 +2071,18 @@ function importHistoryFromHtml(content) {
2071
2071
  existingUrls.add(url);
2072
2072
  imported++;
2073
2073
  }
2074
- state$3.entries.sort(
2074
+ state$4.entries.sort(
2075
2075
  (a, b) => new Date(b.visitedAt).getTime() - new Date(a.visitedAt).getTime()
2076
2076
  );
2077
- if (state$3.entries.length > MAX_HISTORY_ENTRIES) {
2078
- state$3.entries = state$3.entries.slice(0, MAX_HISTORY_ENTRIES);
2077
+ if (state$4.entries.length > MAX_HISTORY_ENTRIES) {
2078
+ state$4.entries = state$4.entries.slice(0, MAX_HISTORY_ENTRIES);
2079
2079
  }
2080
- save$1();
2081
- emit$1();
2080
+ save$2();
2081
+ emit$3();
2082
2082
  return { imported, skipped, errors };
2083
2083
  }
2084
2084
  function flushPersist$3() {
2085
- return persistence$4.flush();
2085
+ return persistence$6.flush();
2086
2086
  }
2087
2087
  const MAX_CONSOLE_ENTRIES = 500;
2088
2088
  const MAX_NETWORK_ENTRIES = 200;
@@ -2439,18 +2439,18 @@ class DevToolsSession {
2439
2439
  if (result?.__error) throw new Error(result.__error);
2440
2440
  return { type, origin, entries: result ?? {} };
2441
2441
  }
2442
- async setStorage(type, key, value) {
2442
+ async setStorage(type, key2, value) {
2443
2443
  const storageType = type === "localStorage" ? "localStorage" : "sessionStorage";
2444
2444
  if (value === null) {
2445
2445
  await this.wc.executeJavaScript(
2446
- `window.${storageType}.removeItem(${JSON.stringify(key)})`
2446
+ `window.${storageType}.removeItem(${JSON.stringify(key2)})`
2447
2447
  );
2448
- return `Removed "${key}" from ${type}`;
2448
+ return `Removed "${key2}" from ${type}`;
2449
2449
  }
2450
2450
  await this.wc.executeJavaScript(
2451
- `window.${storageType}.setItem(${JSON.stringify(key)}, ${JSON.stringify(value)})`
2451
+ `window.${storageType}.setItem(${JSON.stringify(key2)}, ${JSON.stringify(value)})`
2452
2452
  );
2453
- return `Set ${type}["${key}"] = ${value.length > 80 ? value.slice(0, 77) + "..." : value}`;
2453
+ return `Set ${type}["${key2}"] = ${value.length > 80 ? value.slice(0, 77) + "..." : value}`;
2454
2454
  }
2455
2455
  // ---------------------------------------------------------------------------
2456
2456
  // Performance
@@ -3015,23 +3015,23 @@ class TabManager {
3015
3015
  async saveTabAsPdf(id) {
3016
3016
  const tab = this.tabs.get(id);
3017
3017
  if (!tab) return null;
3018
- const { canceled, filePath } = await electron.dialog.showSaveDialog({
3018
+ const { canceled, filePath: filePath2 } = await electron.dialog.showSaveDialog({
3019
3019
  title: "Save Page as PDF",
3020
3020
  defaultPath: sanitizePdfFilename(tab.state.title || "Vessel Page"),
3021
3021
  filters: [{ name: "PDF", extensions: ["pdf"] }]
3022
3022
  });
3023
- if (canceled || !filePath) return null;
3023
+ if (canceled || !filePath2) return null;
3024
3024
  const data = await tab.view.webContents.printToPDF({
3025
3025
  printBackground: true
3026
3026
  });
3027
- await fs.promises.writeFile(filePath, data);
3028
- return filePath;
3027
+ await fs.promises.writeFile(filePath2, data);
3028
+ return filePath2;
3029
3029
  }
3030
3030
  async savePage(id, format = "MHTML") {
3031
3031
  const tab = this.tabs.get(id);
3032
3032
  if (!tab) return null;
3033
3033
  const ext = format === "MHTML" ? "mhtml" : "html";
3034
- const { canceled, filePath } = await electron.dialog.showSaveDialog({
3034
+ const { canceled, filePath: filePath2 } = await electron.dialog.showSaveDialog({
3035
3035
  title: "Save Page As",
3036
3036
  defaultPath: sanitizePageFilename(
3037
3037
  tab.state.title || "Vessel Page",
@@ -3041,9 +3041,9 @@ class TabManager {
3041
3041
  { name: format === "MHTML" ? "MHTML" : "HTML", extensions: [ext] }
3042
3042
  ]
3043
3043
  });
3044
- if (canceled || !filePath) return null;
3045
- await tab.view.webContents.savePage(filePath, format);
3046
- return filePath;
3044
+ if (canceled || !filePath2) return null;
3045
+ await tab.view.webContents.savePage(filePath2, format);
3046
+ return filePath2;
3047
3047
  }
3048
3048
  getActiveTab() {
3049
3049
  return this.activeTabId ? this.tabs.get(this.activeTabId) : void 0;
@@ -3127,11 +3127,11 @@ class TabManager {
3127
3127
  this.pinTab(ids[index]);
3128
3128
  }
3129
3129
  if (tab.groupName && ids[index]) {
3130
- const key = `${tab.groupName}|${tab.groupColor ?? "blue"}`;
3131
- let groupId = restoredGroups.get(key);
3130
+ const key2 = `${tab.groupName}|${tab.groupColor ?? "blue"}`;
3131
+ let groupId = restoredGroups.get(key2);
3132
3132
  if (!groupId) {
3133
3133
  groupId = crypto$1.randomUUID();
3134
- restoredGroups.set(key, groupId);
3134
+ restoredGroups.set(key2, groupId);
3135
3135
  this.tabGroups.set(groupId, {
3136
3136
  id: groupId,
3137
3137
  name: tab.groupName,
@@ -3456,6 +3456,11 @@ const Channels = {
3456
3456
  DOWNLOAD_STARTED: "download:started",
3457
3457
  DOWNLOAD_PROGRESS: "download:progress",
3458
3458
  DOWNLOAD_DONE: "download:done",
3459
+ DOWNLOADS_GET: "downloads:get",
3460
+ DOWNLOADS_CLEAR: "downloads:clear",
3461
+ DOWNLOADS_OPEN: "downloads:open",
3462
+ DOWNLOADS_SHOW_IN_FOLDER: "downloads:show-in-folder",
3463
+ DOWNLOADS_UPDATE: "downloads:update",
3459
3464
  // Premium
3460
3465
  PREMIUM_GET_STATE: "premium:get-state",
3461
3466
  PREMIUM_ACTIVATION_START: "premium:activation-start",
@@ -3518,7 +3523,14 @@ const Channels = {
3518
3523
  CODEX_START_AUTH: "codex:start-auth",
3519
3524
  CODEX_CANCEL_AUTH: "codex:cancel-auth",
3520
3525
  CODEX_AUTH_STATUS: "codex:auth-status",
3521
- CODEX_DISCONNECT: "codex:disconnect"
3526
+ CODEX_DISCONNECT: "codex:disconnect",
3527
+ // Updates
3528
+ UPDATES_CHECK: "updates:check",
3529
+ UPDATES_OPEN_DOWNLOAD: "updates:open-download",
3530
+ // Permissions
3531
+ PERMISSIONS_GET: "permissions:get",
3532
+ PERMISSIONS_CLEAR: "permissions:clear",
3533
+ PERMISSIONS_CLEAR_ORIGIN: "permissions:clear-origin"
3522
3534
  };
3523
3535
  const MAX_DETAIL_ITEMS = 3;
3524
3536
  const MIN_BLOCK_SIMILARITY = 0.82;
@@ -3760,25 +3772,25 @@ function normalizeQueryValue(value) {
3760
3772
  }
3761
3773
  function serializeSnapshotParams(params) {
3762
3774
  return params.map(
3763
- ([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
3775
+ ([key2, value]) => `${encodeURIComponent(key2)}=${encodeURIComponent(value)}`
3764
3776
  ).join("&");
3765
3777
  }
3766
3778
  function normalizeSnapshotParams(entries, pathname) {
3767
3779
  return Array.from(entries).filter(
3768
- ([key, value]) => shouldKeepSnapshotQueryParam(pathname, key, value)
3769
- ).map(([key, value]) => [
3770
- key.trim().toLowerCase(),
3780
+ ([key2, value]) => shouldKeepSnapshotQueryParam(pathname, key2, value)
3781
+ ).map(([key2, value]) => [
3782
+ key2.trim().toLowerCase(),
3771
3783
  normalizeQueryValue(value)
3772
3784
  ]).sort(
3773
3785
  ([keyA, valueA], [keyB, valueB]) => keyA === keyB ? valueA.localeCompare(valueB) : keyA.localeCompare(keyB)
3774
3786
  );
3775
3787
  }
3776
3788
  function shouldKeepSnapshotQueryParam(pathname, rawKey, value) {
3777
- const key = rawKey.trim().toLowerCase();
3778
- if (!key || !value.trim()) return false;
3779
- if (key.startsWith("utm_")) return false;
3780
- if (TRACKING_QUERY_KEYS.has(key)) return false;
3781
- if (SNAPSHOT_QUERY_KEYS.has(key)) return true;
3789
+ const key2 = rawKey.trim().toLowerCase();
3790
+ if (!key2 || !value.trim()) return false;
3791
+ if (key2.startsWith("utm_")) return false;
3792
+ if (TRACKING_QUERY_KEYS.has(key2)) return false;
3793
+ if (SNAPSHOT_QUERY_KEYS.has(key2)) return true;
3782
3794
  return /\/(search|results|browse|discover|find|category|tag|topics?|collections?|list)(\/|$)/i.test(
3783
3795
  pathname
3784
3796
  );
@@ -3871,7 +3883,7 @@ function load$2() {
3871
3883
  });
3872
3884
  return snapshots;
3873
3885
  }
3874
- const persistence$3 = createDebouncedJsonPersistence({
3886
+ const persistence$5 = createDebouncedJsonPersistence({
3875
3887
  debounceMs: SAVE_DEBOUNCE_MS$3,
3876
3888
  filePath: getFilePath$1(),
3877
3889
  getValue: () => snapshots,
@@ -3890,21 +3902,21 @@ function getSnapshot(normalizedUrl) {
3890
3902
  }
3891
3903
  function saveSnapshot(rawUrl, title, textContent, headings) {
3892
3904
  const s = load$2();
3893
- const key = normalizeUrl(rawUrl);
3905
+ const key2 = normalizeUrl(rawUrl);
3894
3906
  const snapshot = {
3895
- url: key,
3907
+ url: key2,
3896
3908
  title,
3897
3909
  textContent: textContent.slice(0, MAX_TEXT_LENGTH),
3898
3910
  headings: headings.map((h) => `${"#".repeat(h.level)} ${h.text}`).join("\n"),
3899
3911
  capturedAt: (/* @__PURE__ */ new Date()).toISOString()
3900
3912
  };
3901
- s.delete(key);
3902
- s.set(key, snapshot);
3903
- persistence$3.schedule();
3913
+ s.delete(key2);
3914
+ s.set(key2, snapshot);
3915
+ persistence$5.schedule();
3904
3916
  return snapshot;
3905
3917
  }
3906
3918
  function flushPersist$2() {
3907
- return persistence$3.flush();
3919
+ return persistence$5.flush();
3908
3920
  }
3909
3921
  const SEARCH_ENGINE_HOSTS = [
3910
3922
  "google.",
@@ -4219,11 +4231,11 @@ function sanitizeValue(value, depth = 0) {
4219
4231
  const record = asRecord(value);
4220
4232
  if (!record || depth >= MAX_DEPTH) return void 0;
4221
4233
  const objectValue = {};
4222
- for (const [key, entry] of Object.entries(record)) {
4223
- if (SKIP_FIELDS.has(key)) continue;
4234
+ for (const [key2, entry] of Object.entries(record)) {
4235
+ if (SKIP_FIELDS.has(key2)) continue;
4224
4236
  const normalized = sanitizeValue(entry, depth + 1);
4225
4237
  if (normalized !== void 0) {
4226
- objectValue[key] = normalized;
4238
+ objectValue[key2] = normalized;
4227
4239
  }
4228
4240
  }
4229
4241
  return Object.keys(objectValue).length > 0 ? objectValue : void 0;
@@ -4231,10 +4243,10 @@ function sanitizeValue(value, depth = 0) {
4231
4243
  function buildNormalizedAttributes(record, types) {
4232
4244
  const attributes = {};
4233
4245
  const consumed = /* @__PURE__ */ new Set();
4234
- const consume = (key, value) => {
4246
+ const consume = (key2, value) => {
4235
4247
  if (value === void 0) return;
4236
- consumed.add(key);
4237
- attributes[key] = value;
4248
+ consumed.add(key2);
4249
+ attributes[key2] = value;
4238
4250
  };
4239
4251
  if (types.includes("Recipe")) {
4240
4252
  consume("yield", sanitizeValue(record.recipeYield));
@@ -4278,14 +4290,14 @@ function buildNormalizedAttributes(record, types) {
4278
4290
  attributes.questions = questions;
4279
4291
  }
4280
4292
  }
4281
- for (const [key, value] of Object.entries(record)) {
4282
- if (SKIP_FIELDS.has(key) || consumed.has(key)) continue;
4283
- if (key === "name" || key === "headline" || key === "url" || key === "description") {
4293
+ for (const [key2, value] of Object.entries(record)) {
4294
+ if (SKIP_FIELDS.has(key2) || consumed.has(key2)) continue;
4295
+ if (key2 === "name" || key2 === "headline" || key2 === "url" || key2 === "description") {
4284
4296
  continue;
4285
4297
  }
4286
4298
  const normalized = sanitizeValue(value);
4287
4299
  if (normalized !== void 0) {
4288
- attributes[key] = normalized;
4300
+ attributes[key2] = normalized;
4289
4301
  }
4290
4302
  }
4291
4303
  return attributes;
@@ -4305,7 +4317,7 @@ function collectCandidateEntities(value, results = [], seen = /* @__PURE__ */ ne
4305
4317
  if (types.length > 0 || hasIdentity) {
4306
4318
  results.push(record);
4307
4319
  }
4308
- for (const key of [
4320
+ for (const key2 of [
4309
4321
  "@graph",
4310
4322
  "mainEntity",
4311
4323
  "mainEntityOfPage",
@@ -4318,7 +4330,7 @@ function collectCandidateEntities(value, results = [], seen = /* @__PURE__ */ ne
4318
4330
  "acceptedAnswer",
4319
4331
  "suggestedAnswer"
4320
4332
  ]) {
4321
- collectCandidateEntities(record[key], results, seen);
4333
+ collectCandidateEntities(record[key2], results, seen);
4322
4334
  }
4323
4335
  return results;
4324
4336
  }
@@ -4331,11 +4343,11 @@ function dedupeKey(entity) {
4331
4343
  JSON.stringify(entity.attributes)
4332
4344
  ].join("::");
4333
4345
  }
4334
- function extractEntitiesFromRecords(records, source) {
4335
- if (!records || records.length === 0) return [];
4346
+ function extractEntitiesFromRecords(records2, source) {
4347
+ if (!records2 || records2.length === 0) return [];
4336
4348
  const entities = [];
4337
4349
  const seen = /* @__PURE__ */ new Set();
4338
- for (const candidate of collectCandidateEntities(records)) {
4350
+ for (const candidate of collectCandidateEntities(records2)) {
4339
4351
  const types = getTypes(candidate);
4340
4352
  const name = firstString(candidate.name, candidate.headline);
4341
4353
  const url = firstString(candidate.url, candidate["@id"]);
@@ -4355,9 +4367,9 @@ function extractEntitiesFromRecords(records, source) {
4355
4367
  addIfPresent(entity, "name", name);
4356
4368
  addIfPresent(entity, "url", url);
4357
4369
  addIfPresent(entity, "description", description);
4358
- const key = dedupeKey(entity);
4359
- if (seen.has(key)) continue;
4360
- seen.add(key);
4370
+ const key2 = dedupeKey(entity);
4371
+ if (seen.has(key2)) continue;
4372
+ seen.add(key2);
4361
4373
  entities.push(entity);
4362
4374
  }
4363
4375
  return entities.slice(0, 25);
@@ -4380,13 +4392,13 @@ function extractEntityFromMetaTags(metaTags, pageTitle, pageUrl) {
4380
4392
  const url = metaTags["og:url"] || metaTags.canonical || pageUrl;
4381
4393
  const types = getMetaType(metaTags);
4382
4394
  const attributes = {};
4383
- for (const [key, value] of Object.entries(metaTags)) {
4384
- if (key === "og:title" || key === "twitter:title" || key === "title" || key === "og:description" || key === "description" || key === "twitter:description" || key === "og:url" || key === "canonical") {
4395
+ for (const [key2, value] of Object.entries(metaTags)) {
4396
+ if (key2 === "og:title" || key2 === "twitter:title" || key2 === "title" || key2 === "og:description" || key2 === "description" || key2 === "twitter:description" || key2 === "og:url" || key2 === "canonical") {
4385
4397
  continue;
4386
4398
  }
4387
4399
  const normalized = sanitizeValue(value);
4388
4400
  if (normalized !== void 0) {
4389
- attributes[key] = normalized;
4401
+ attributes[key2] = normalized;
4390
4402
  }
4391
4403
  }
4392
4404
  const entity = {
@@ -4439,9 +4451,9 @@ function extractStructuredDataFromJsonLd(jsonLd, microdata, rdfa, metaTags, page
4439
4451
  const deduped = [];
4440
4452
  const seen = /* @__PURE__ */ new Set();
4441
4453
  for (const entity of candidates) {
4442
- const key = dedupeKey(entity);
4443
- if (seen.has(key)) continue;
4444
- seen.add(key);
4454
+ const key2 = dedupeKey(entity);
4455
+ if (seen.has(key2)) continue;
4456
+ seen.add(key2);
4445
4457
  deduped.push(entity);
4446
4458
  }
4447
4459
  if (deduped.length > 0) {
@@ -4455,9 +4467,9 @@ function extractStructuredDataFromJsonLd(jsonLd, microdata, rdfa, metaTags, page
4455
4467
  pageHeadings
4456
4468
  );
4457
4469
  }
4458
- function addIfPresent(target, key, value) {
4470
+ function addIfPresent(target, key2, value) {
4459
4471
  if (value !== void 0) {
4460
- target[key] = value;
4472
+ target[key2] = value;
4461
4473
  }
4462
4474
  }
4463
4475
  function okResult(value) {
@@ -4770,8 +4782,8 @@ function trackProviderConfigured(providerId) {
4770
4782
  provider_id: providerId
4771
4783
  });
4772
4784
  }
4773
- function trackSettingChanged(key) {
4774
- trackEvent("setting_changed", { setting_key: key });
4785
+ function trackSettingChanged(key2) {
4786
+ trackEvent("setting_changed", { setting_key: key2 });
4775
4787
  }
4776
4788
  function trackApprovalModeChanged(mode) {
4777
4789
  trackEvent("approval_mode_changed", { mode });
@@ -4953,10 +4965,10 @@ function mapFormFields(forms, interactiveElements) {
4953
4965
  }
4954
4966
  }
4955
4967
  for (const el of interactiveElements) {
4956
- const key = el.selector || el.name || el.label || String(el.index);
4957
- if (formFieldSelectors.has(key)) {
4968
+ const key2 = el.selector || el.name || el.label || String(el.index);
4969
+ if (formFieldSelectors.has(key2)) {
4958
4970
  fields.push({
4959
- name: el.name || el.label || key,
4971
+ name: el.name || el.label || key2,
4960
4972
  type: mapInputType(el),
4961
4973
  label: el.label,
4962
4974
  required: el.required,
@@ -6195,12 +6207,12 @@ function loadHistory() {
6195
6207
  return next;
6196
6208
  }
6197
6209
  });
6198
- for (const [key, bursts] of loaded.entries()) {
6199
- recentPageDiffBursts.set(key, bursts);
6210
+ for (const [key2, bursts] of loaded.entries()) {
6211
+ recentPageDiffBursts.set(key2, bursts);
6200
6212
  }
6201
6213
  return recentPageDiffBursts;
6202
6214
  }
6203
- const persistence$2 = createDebouncedJsonPersistence({
6215
+ const persistence$4 = createDebouncedJsonPersistence({
6204
6216
  debounceMs: SAVE_DEBOUNCE_MS$2,
6205
6217
  filePath: getHistoryFilePath(),
6206
6218
  getValue: () => recentPageDiffBursts,
@@ -6217,20 +6229,20 @@ function getLatestPageDiff(rawUrl) {
6217
6229
  }
6218
6230
  function getPageDiffBursts(rawUrl) {
6219
6231
  if (!shouldTrackSnapshotUrl(rawUrl)) return [];
6220
- const key = normalizeUrl(rawUrl);
6232
+ const key2 = normalizeUrl(rawUrl);
6221
6233
  const history = loadHistory();
6222
- const bursts = prunePageDiffHistory(history.get(key) ?? [], {
6234
+ const bursts = prunePageDiffHistory(history.get(key2) ?? [], {
6223
6235
  maxAgeDays: MAX_HISTORY_DAYS,
6224
6236
  maxItems: MAX_PERSISTED_DIFF_BURSTS
6225
6237
  });
6226
- const current = history.get(key) ?? [];
6238
+ const current = history.get(key2) ?? [];
6227
6239
  if (current.length !== bursts.length) {
6228
6240
  if (bursts.length > 0) {
6229
- history.set(key, bursts);
6241
+ history.set(key2, bursts);
6230
6242
  } else {
6231
- history.delete(key);
6243
+ history.delete(key2);
6232
6244
  }
6233
- persistence$2.schedule();
6245
+ persistence$4.schedule();
6234
6246
  }
6235
6247
  return bursts.slice().reverse();
6236
6248
  }
@@ -6238,20 +6250,20 @@ function summarizeDiffBurst(diff) {
6238
6250
  const items = diff.changes.slice(0, 2).map((change) => `${change.section}: ${change.summary}`);
6239
6251
  return items.join(" | ");
6240
6252
  }
6241
- function enrichWithBurstHistory(key, diff) {
6253
+ function enrichWithBurstHistory(key2, diff) {
6242
6254
  const detectedAt = (/* @__PURE__ */ new Date()).toISOString();
6243
6255
  const nextBurst = {
6244
6256
  detectedAt,
6245
6257
  summary: summarizeDiffBurst(diff)
6246
6258
  };
6247
6259
  const history = loadHistory();
6248
- const bursts = appendPageDiffHistoryItem(history.get(key) ?? [], nextBurst, {
6260
+ const bursts = appendPageDiffHistoryItem(history.get(key2) ?? [], nextBurst, {
6249
6261
  maxAgeDays: MAX_HISTORY_DAYS,
6250
6262
  maxItems: MAX_PERSISTED_DIFF_BURSTS,
6251
6263
  now: Date.parse(detectedAt)
6252
6264
  });
6253
- history.set(key, bursts);
6254
- persistence$2.schedule();
6265
+ history.set(key2, bursts);
6266
+ persistence$4.schedule();
6255
6267
  const recentBursts = bursts.slice(-5);
6256
6268
  return {
6257
6269
  ...diff,
@@ -6264,8 +6276,8 @@ function enrichWithBurstHistory(key, diff) {
6264
6276
  async function capturePageSnapshot(url, wc, sendToRendererViews) {
6265
6277
  try {
6266
6278
  if (!shouldTrackSnapshotUrl(url)) return;
6267
- const key = normalizeUrl(url);
6268
- const oldSnap = getSnapshot(key);
6279
+ const key2 = normalizeUrl(url);
6280
+ const oldSnap = getSnapshot(key2);
6269
6281
  const content = await extractContent(wc);
6270
6282
  const textContent = content.content || "";
6271
6283
  const title = content.title || "";
@@ -6274,14 +6286,14 @@ async function capturePageSnapshot(url, wc, sendToRendererViews) {
6274
6286
  if (oldSnap) {
6275
6287
  const diff = diffSnapshots(oldSnap, textContent, title, currentHeadings);
6276
6288
  if (diff.hasChanges) {
6277
- const enrichedDiff = enrichWithBurstHistory(key, diff);
6278
- latestPageDiffs.set(key, enrichedDiff);
6289
+ const enrichedDiff = enrichWithBurstHistory(key2, diff);
6290
+ latestPageDiffs.set(key2, enrichedDiff);
6279
6291
  sendToRendererViews(Channels.PAGE_CHANGED, enrichedDiff);
6280
6292
  } else {
6281
- latestPageDiffs.delete(key);
6293
+ latestPageDiffs.delete(key2);
6282
6294
  }
6283
6295
  } else {
6284
- latestPageDiffs.delete(key);
6296
+ latestPageDiffs.delete(key2);
6285
6297
  }
6286
6298
  saveSnapshot(url, title, textContent, headings);
6287
6299
  } catch {
@@ -6333,19 +6345,19 @@ function schedulePageSnapshotCapture(wc, sendToRendererViews, delayMs = 0) {
6333
6345
  function enableClipboardShortcuts(view) {
6334
6346
  view.webContents.on("before-input-event", (event, input) => {
6335
6347
  if (!input.control && !input.meta) return;
6336
- const key = input.key.toLowerCase();
6348
+ const key2 = input.key.toLowerCase();
6337
6349
  const wc = view.webContents;
6338
6350
  if (input.type === "keyDown") {
6339
- if (key === "c") {
6351
+ if (key2 === "c") {
6340
6352
  wc.copy();
6341
6353
  event.preventDefault();
6342
- } else if (key === "v") {
6354
+ } else if (key2 === "v") {
6343
6355
  wc.paste();
6344
6356
  event.preventDefault();
6345
- } else if (key === "x") {
6357
+ } else if (key2 === "x") {
6346
6358
  wc.cut();
6347
6359
  event.preventDefault();
6348
- } else if (key === "a") {
6360
+ } else if (key2 === "a") {
6349
6361
  wc.selectAll();
6350
6362
  event.preventDefault();
6351
6363
  }
@@ -6759,7 +6771,7 @@ function onRuntimeHealthChange(listener) {
6759
6771
  };
6760
6772
  }
6761
6773
  function getMcpStatus() {
6762
- return state$2.mcp.status;
6774
+ return state$3.mcp.status;
6763
6775
  }
6764
6776
  function emitRuntimeHealthChange() {
6765
6777
  const snapshot = getRuntimeHealth();
@@ -6767,7 +6779,7 @@ function emitRuntimeHealthChange() {
6767
6779
  listener(snapshot);
6768
6780
  }
6769
6781
  }
6770
- const state$2 = {
6782
+ const state$3 = {
6771
6783
  userDataPath: "",
6772
6784
  settingsPath: "",
6773
6785
  startupIssues: [],
@@ -6780,43 +6792,43 @@ const state$2 = {
6780
6792
  }
6781
6793
  };
6782
6794
  function initializeRuntimeHealth(paths) {
6783
- state$2.userDataPath = paths.userDataPath;
6784
- state$2.settingsPath = paths.settingsPath;
6785
- state$2.mcp.configuredPort = paths.configuredPort;
6786
- state$2.mcp.activePort = null;
6787
- state$2.mcp.endpoint = null;
6788
- state$2.mcp.status = "stopped";
6789
- state$2.mcp.message = "MCP server has not started yet.";
6795
+ state$3.userDataPath = paths.userDataPath;
6796
+ state$3.settingsPath = paths.settingsPath;
6797
+ state$3.mcp.configuredPort = paths.configuredPort;
6798
+ state$3.mcp.activePort = null;
6799
+ state$3.mcp.endpoint = null;
6800
+ state$3.mcp.status = "stopped";
6801
+ state$3.mcp.message = "MCP server has not started yet.";
6790
6802
  emitRuntimeHealthChange();
6791
6803
  }
6792
6804
  function setStartupIssues(issues) {
6793
- state$2.startupIssues = issues.map((issue) => ({ ...issue }));
6805
+ state$3.startupIssues = issues.map((issue) => ({ ...issue }));
6794
6806
  emitRuntimeHealthChange();
6795
6807
  }
6796
6808
  function getRuntimeHealth() {
6797
6809
  return {
6798
- userDataPath: state$2.userDataPath,
6799
- settingsPath: state$2.settingsPath,
6800
- startupIssues: state$2.startupIssues.map((issue) => ({ ...issue })),
6801
- mcp: { ...state$2.mcp }
6810
+ userDataPath: state$3.userDataPath,
6811
+ settingsPath: state$3.settingsPath,
6812
+ startupIssues: state$3.startupIssues.map((issue) => ({ ...issue })),
6813
+ mcp: { ...state$3.mcp }
6802
6814
  };
6803
6815
  }
6804
6816
  function setMcpHealth(update) {
6805
6817
  if (typeof update.configuredPort === "number") {
6806
- state$2.mcp.configuredPort = update.configuredPort;
6818
+ state$3.mcp.configuredPort = update.configuredPort;
6807
6819
  }
6808
6820
  if ("activePort" in update) {
6809
- state$2.mcp.activePort = update.activePort ?? null;
6821
+ state$3.mcp.activePort = update.activePort ?? null;
6810
6822
  }
6811
6823
  if ("endpoint" in update) {
6812
- state$2.mcp.endpoint = update.endpoint ?? null;
6824
+ state$3.mcp.endpoint = update.endpoint ?? null;
6813
6825
  }
6814
- const prevStatus = state$2.mcp.status;
6815
- state$2.mcp.status = update.status;
6816
- state$2.mcp.message = update.message;
6817
- if (prevStatus !== state$2.mcp.status) {
6826
+ const prevStatus = state$3.mcp.status;
6827
+ state$3.mcp.status = update.status;
6828
+ state$3.mcp.message = update.message;
6829
+ if (prevStatus !== state$3.mcp.status) {
6818
6830
  for (const listener of mcpStatusChangeListeners) {
6819
- listener(state$2.mcp.status);
6831
+ listener(state$3.mcp.status);
6820
6832
  }
6821
6833
  }
6822
6834
  emitRuntimeHealthChange();
@@ -7728,8 +7740,8 @@ function scalarArgsForTool(name, scalar) {
7728
7740
  return null;
7729
7741
  }
7730
7742
  function firstStringArg(args, keys) {
7731
- for (const key of keys) {
7732
- const value = args[key];
7743
+ for (const key2 of keys) {
7744
+ const value = args[key2];
7733
7745
  if (typeof value === "string" && value.trim()) {
7734
7746
  return value.trim();
7735
7747
  }
@@ -9020,8 +9032,8 @@ function extractLlamaCppCtxSize(payload) {
9020
9032
  const current = queue.shift();
9021
9033
  if (!current || typeof current !== "object" || visited.has(current)) continue;
9022
9034
  visited.add(current);
9023
- for (const [key, value] of Object.entries(current)) {
9024
- if (typeof value === "number" && Number.isFinite(value) && /^(n_ctx|ctx_size|context_size)$/i.test(key)) {
9035
+ for (const [key2, value] of Object.entries(current)) {
9036
+ if (typeof value === "number" && Number.isFinite(value) && /^(n_ctx|ctx_size|context_size)$/i.test(key2)) {
9025
9037
  return value;
9026
9038
  }
9027
9039
  if (value && typeof value === "object") {
@@ -9243,14 +9255,14 @@ function normalizeStoredRadioOption(option) {
9243
9255
  function dedupeCandidates(actions) {
9244
9256
  const seen = /* @__PURE__ */ new Set();
9245
9257
  return actions.filter((action) => {
9246
- const key = [
9258
+ const key2 = [
9247
9259
  action.selector || "",
9248
9260
  action.label || "",
9249
9261
  action.role || "",
9250
9262
  action.labelSource || ""
9251
9263
  ].join("::");
9252
- if (seen.has(key)) return false;
9253
- seen.add(key);
9264
+ if (seen.has(key2)) return false;
9265
+ seen.add(key2);
9254
9266
  return true;
9255
9267
  });
9256
9268
  }
@@ -9495,11 +9507,11 @@ function getQuantityElements(page) {
9495
9507
  ];
9496
9508
  return elements.filter((el) => {
9497
9509
  if (!isQuantityLike(el)) return false;
9498
- const key = String(
9510
+ const key2 = String(
9499
9511
  el.index ?? el.selector ?? `${el.type}|${el.name || ""}|${el.label || ""}|${el.value || ""}`
9500
9512
  );
9501
- if (seen.has(key)) return false;
9502
- seen.add(key);
9513
+ if (seen.has(key2)) return false;
9514
+ seen.add(key2);
9503
9515
  return true;
9504
9516
  });
9505
9517
  }
@@ -9541,9 +9553,9 @@ function getCartItemLinks(page) {
9541
9553
  return false;
9542
9554
  }
9543
9555
  if (blockedText.test(text) || blockedHref.test(href)) return false;
9544
- const key = `${normalizeComparable(text)}|${normalizeUrlForMatch(href) || href}`;
9545
- if (seen.has(key)) return false;
9546
- seen.add(key);
9556
+ const key2 = `${normalizeComparable(text)}|${normalizeUrlForMatch(href) || href}`;
9557
+ if (seen.has(key2)) return false;
9558
+ seen.add(key2);
9547
9559
  return true;
9548
9560
  }).slice(0, 12);
9549
9561
  }
@@ -9644,11 +9656,11 @@ function getPurchaseActionElements(page, options) {
9644
9656
  if (!isPurchaseActionElement(el)) return false;
9645
9657
  if (visibleOnly && !isVisibleToUser(el)) return false;
9646
9658
  if (el.blockedByOverlay) return false;
9647
- const key = String(
9659
+ const key2 = String(
9648
9660
  el.index ?? el.selector ?? `${el.type}|${el.text || ""}|${el.label || ""}|${el.href || ""}`
9649
9661
  );
9650
- if (seen.has(key)) return false;
9651
- seen.add(key);
9662
+ if (seen.has(key2)) return false;
9663
+ seen.add(key2);
9652
9664
  return true;
9653
9665
  }).sort((a, b) => {
9654
9666
  const delta = purchaseActionPriority(a) - purchaseActionPriority(b);
@@ -9665,10 +9677,10 @@ function getOffscreenPurchaseActionElements(page) {
9665
9677
  )
9666
9678
  );
9667
9679
  return getPurchaseActionElements(page, { visibleOnly: false }).filter((el) => {
9668
- const key = String(
9680
+ const key2 = String(
9669
9681
  el.index ?? el.selector ?? `${el.type}|${el.text || ""}|${el.label || ""}|${el.href || ""}`
9670
9682
  );
9671
- return !visibleKeys.has(key) && el.visible !== false;
9683
+ return !visibleKeys.has(key2) && el.visible !== false;
9672
9684
  });
9673
9685
  }
9674
9686
  function getDialogFocusedElements(page) {
@@ -9934,7 +9946,7 @@ function formatStructuredValue(value, depth = 0) {
9934
9946
  const rendered = value.map((item) => formatStructuredValue(item, depth + 1)).filter(Boolean).slice(0, depth === 0 ? 8 : 5);
9935
9947
  return rendered.join(depth === 0 ? ", " : " | ");
9936
9948
  }
9937
- const entries = Object.entries(value).slice(0, 6).map(([key, entry]) => `${key}: ${formatStructuredValue(entry, depth + 1)}`).filter((entry) => !entry.endsWith(": "));
9949
+ const entries = Object.entries(value).slice(0, 6).map(([key2, entry]) => `${key2}: ${formatStructuredValue(entry, depth + 1)}`).filter((entry) => !entry.endsWith(": "));
9938
9950
  return entries.join(", ");
9939
9951
  }
9940
9952
  function formatStructuredEntities(entities) {
@@ -9949,13 +9961,13 @@ function formatStructuredEntities(entities) {
9949
9961
  if (entity.url && entity.url !== entity.name) {
9950
9962
  lines.push(` url: ${entity.url}`);
9951
9963
  }
9952
- for (const [key, value] of Object.entries(entity.attributes).slice(
9964
+ for (const [key2, value] of Object.entries(entity.attributes).slice(
9953
9965
  0,
9954
9966
  8
9955
9967
  )) {
9956
9968
  const rendered = formatStructuredValue(value);
9957
9969
  if (rendered) {
9958
- lines.push(` ${key}: ${rendered}`);
9970
+ lines.push(` ${key2}: ${rendered}`);
9959
9971
  }
9960
9972
  }
9961
9973
  return lines.join("\n");
@@ -10053,17 +10065,17 @@ function formatJsonLd(items) {
10053
10065
  }
10054
10066
  return String(val);
10055
10067
  };
10056
- for (const key of priorityFields) {
10057
- if (key in item) {
10058
- seen.add(key);
10059
- const rendered = renderValue(item[key]);
10060
- if (rendered) lines.push(` ${key}: ${rendered}`);
10068
+ for (const key2 of priorityFields) {
10069
+ if (key2 in item) {
10070
+ seen.add(key2);
10071
+ const rendered = renderValue(item[key2]);
10072
+ if (rendered) lines.push(` ${key2}: ${rendered}`);
10061
10073
  }
10062
10074
  }
10063
- for (const [key, val] of Object.entries(item)) {
10064
- if (seen.has(key) || SKIP.has(key) || key === "@type") continue;
10075
+ for (const [key2, val] of Object.entries(item)) {
10076
+ if (seen.has(key2) || SKIP.has(key2) || key2 === "@type") continue;
10065
10077
  const rendered = renderValue(val);
10066
- if (rendered) lines.push(` ${key}: ${rendered}`);
10078
+ if (rendered) lines.push(` ${key2}: ${rendered}`);
10067
10079
  }
10068
10080
  lines.push("");
10069
10081
  }
@@ -10198,9 +10210,9 @@ function getResultCandidates(page) {
10198
10210
  );
10199
10211
  const seen = /* @__PURE__ */ new Set();
10200
10212
  return scored.map(({ element }) => element).filter((element) => {
10201
- const key = `${normalizeComparable(element.text || "")}|${normalizeUrlForMatch(element.href) || ""}`;
10202
- if (seen.has(key)) return false;
10203
- seen.add(key);
10213
+ const key2 = `${normalizeComparable(element.text || "")}|${normalizeUrlForMatch(element.href) || ""}`;
10214
+ if (seen.has(key2)) return false;
10215
+ seen.add(key2);
10204
10216
  return true;
10205
10217
  });
10206
10218
  }
@@ -10997,9 +11009,9 @@ function getCompactPrimaryResultLinks(page, options) {
10997
11009
  })).filter(({ score }) => score >= (listingLike ? 5 : 7)).sort(
10998
11010
  (a, b) => b.score - a.score || (a.element.index ?? Number.MAX_SAFE_INTEGER) - (b.element.index ?? Number.MAX_SAFE_INTEGER)
10999
11011
  ).map(({ element }) => element).filter((element) => {
11000
- const key = `${normalizeComparable(element.text)}|${normalizeUrlForMatch(element.href) || ""}`;
11001
- if (seen.has(key)) return false;
11002
- seen.add(key);
11012
+ const key2 = `${normalizeComparable(element.text)}|${normalizeUrlForMatch(element.href) || ""}`;
11013
+ if (seen.has(key2)) return false;
11014
+ seen.add(key2);
11003
11015
  return true;
11004
11016
  }).slice(0, max);
11005
11017
  }
@@ -11045,9 +11057,9 @@ function formatElement(element) {
11045
11057
  function uniqueElements(elements) {
11046
11058
  const seen = /* @__PURE__ */ new Set();
11047
11059
  return elements.filter((element) => {
11048
- const key = `${element.index ?? ""}|${element.type}|${elementLabel(element)}|${element.href ?? ""}`;
11049
- if (seen.has(key)) return false;
11050
- seen.add(key);
11060
+ const key2 = `${element.index ?? ""}|${element.type}|${elementLabel(element)}|${element.href ?? ""}`;
11061
+ if (seen.has(key2)) return false;
11062
+ seen.add(key2);
11051
11063
  return true;
11052
11064
  });
11053
11065
  }
@@ -12370,12 +12382,12 @@ function normalizeAgentHints(value) {
12370
12382
  return void 0;
12371
12383
  }
12372
12384
  const normalized = Object.fromEntries(
12373
- Object.entries(value).map(([key, hint]) => [key.trim(), normalizeOptionalString(hint)]).filter((entry) => Boolean(entry[0] && entry[1]))
12385
+ Object.entries(value).map(([key2, hint]) => [key2.trim(), normalizeOptionalString(hint)]).filter((entry) => Boolean(entry[0] && entry[1]))
12374
12386
  );
12375
12387
  return Object.keys(normalized).length > 0 ? normalized : void 0;
12376
12388
  }
12377
- function hasOwn(value, key) {
12378
- return Object.prototype.hasOwnProperty.call(value, key);
12389
+ function hasOwn(value, key2) {
12390
+ return Object.prototype.hasOwnProperty.call(value, key2);
12379
12391
  }
12380
12392
  function normalizeBookmarkMetadata(input) {
12381
12393
  const normalized = {};
@@ -12413,7 +12425,7 @@ const UNSORTED_ID = "unsorted";
12413
12425
  const ARCHIVE_FOLDER_NAME = "Archive";
12414
12426
  const NETSCAPE_BOOKMARKS_DOCTYPE = "<!DOCTYPE NETSCAPE-Bookmark-file-1>";
12415
12427
  const SAVE_DEBOUNCE_MS$1 = 250;
12416
- let state$1 = null;
12428
+ let state$2 = null;
12417
12429
  const listeners = /* @__PURE__ */ new Set();
12418
12430
  function cloneState(current) {
12419
12431
  return {
@@ -12428,18 +12440,18 @@ function createPersistence() {
12428
12440
  return createDebouncedJsonPersistence({
12429
12441
  debounceMs: SAVE_DEBOUNCE_MS$1,
12430
12442
  filePath: getBookmarksPath(),
12431
- getValue: () => state$1,
12443
+ getValue: () => state$2,
12432
12444
  logLabel: "bookmarks"
12433
12445
  });
12434
12446
  }
12435
- let persistence$1 = null;
12447
+ let persistence$3 = null;
12436
12448
  function getPersistence() {
12437
- persistence$1 ??= createPersistence();
12438
- return persistence$1;
12449
+ persistence$3 ??= createPersistence();
12450
+ return persistence$3;
12439
12451
  }
12440
12452
  function load$1() {
12441
- if (state$1) return state$1;
12442
- state$1 = loadJsonFile({
12453
+ if (state$2) return state$2;
12454
+ state$2 = loadJsonFile({
12443
12455
  filePath: getBookmarksPath(),
12444
12456
  fallback: { folders: [], bookmarks: [] },
12445
12457
  parse: (raw) => {
@@ -12450,21 +12462,21 @@ function load$1() {
12450
12462
  };
12451
12463
  }
12452
12464
  });
12453
- return state$1;
12465
+ return state$2;
12454
12466
  }
12455
- function save() {
12467
+ function save$1() {
12456
12468
  getPersistence().schedule();
12457
12469
  }
12458
12470
  function assignDefinedBookmarkFields(bookmark, fields) {
12459
12471
  if (!fields) return;
12460
- for (const [key, value] of Object.entries(fields)) {
12472
+ for (const [key2, value] of Object.entries(fields)) {
12461
12473
  if (value === void 0) continue;
12462
- Object.assign(bookmark, { [key]: value });
12474
+ Object.assign(bookmark, { [key2]: value });
12463
12475
  }
12464
12476
  }
12465
- function emit() {
12466
- if (!state$1) return;
12467
- const snapshot = cloneState(state$1);
12477
+ function emit$2() {
12478
+ if (!state$2) return;
12479
+ const snapshot = cloneState(state$2);
12468
12480
  for (const listener of listeners) {
12469
12481
  listener(snapshot);
12470
12482
  }
@@ -12483,7 +12495,7 @@ function getBookmarkDescription(bookmark) {
12483
12495
  bookmark.intent ? `Intent: ${bookmark.intent}` : "",
12484
12496
  bookmark.expectedContent ? `Expected content: ${bookmark.expectedContent}` : "",
12485
12497
  bookmark.keyFields?.length ? `Key fields: ${bookmark.keyFields.join(", ")}` : "",
12486
- bookmark.agentHints && Object.keys(bookmark.agentHints).length > 0 ? `Agent hints: ${Object.entries(bookmark.agentHints).map(([key, value]) => `${key}: ${value}`).join("; ")}` : ""
12498
+ bookmark.agentHints && Object.keys(bookmark.agentHints).length > 0 ? `Agent hints: ${Object.entries(bookmark.agentHints).map(([key2, value]) => `${key2}: ${value}`).join("; ")}` : ""
12487
12499
  ].filter(Boolean);
12488
12500
  return lines.join("\n");
12489
12501
  }
@@ -12586,28 +12598,28 @@ function subscribe(listener) {
12586
12598
  };
12587
12599
  }
12588
12600
  function clearAll() {
12589
- state$1 = { folders: [], bookmarks: [] };
12590
- save();
12591
- emit();
12601
+ state$2 = { folders: [], bookmarks: [] };
12602
+ save$1();
12603
+ emit$2();
12592
12604
  }
12593
12605
  function getBookmark(id) {
12594
12606
  load$1();
12595
- const bookmark = state$1.bookmarks.find((item) => item.id === id);
12607
+ const bookmark = state$2.bookmarks.find((item) => item.id === id);
12596
12608
  return bookmark ? { ...bookmark } : null;
12597
12609
  }
12598
12610
  function getBookmarkByUrl(url) {
12599
12611
  load$1();
12600
12612
  const normalized = url.trim();
12601
12613
  if (!normalized) return null;
12602
- const bookmark = [...state$1.bookmarks].reverse().find((item) => item.url === normalized);
12614
+ const bookmark = [...state$2.bookmarks].reverse().find((item) => item.url === normalized);
12603
12615
  return bookmark ? { ...bookmark } : null;
12604
12616
  }
12605
12617
  function getBookmarkByUrlInFolder(url, folderId) {
12606
12618
  load$1();
12607
12619
  const normalizedUrl = url.trim();
12608
12620
  if (!normalizedUrl) return null;
12609
- const targetFolderId = folderId && folderId !== UNSORTED_ID ? state$1.folders.find((f) => f.id === folderId)?.id ?? UNSORTED_ID : UNSORTED_ID;
12610
- const bookmark = [...state$1.bookmarks].reverse().find(
12621
+ const targetFolderId = folderId && folderId !== UNSORTED_ID ? state$2.folders.find((f) => f.id === folderId)?.id ?? UNSORTED_ID : UNSORTED_ID;
12622
+ const bookmark = [...state$2.bookmarks].reverse().find(
12611
12623
  (item) => item.url === normalizedUrl && item.folderId === targetFolderId
12612
12624
  );
12613
12625
  return bookmark ? { ...bookmark } : null;
@@ -12615,14 +12627,14 @@ function getBookmarkByUrlInFolder(url, folderId) {
12615
12627
  function getFolder(id) {
12616
12628
  load$1();
12617
12629
  if (!id || id === UNSORTED_ID) return null;
12618
- const folder = state$1.folders.find((item) => item.id === id);
12630
+ const folder = state$2.folders.find((item) => item.id === id);
12619
12631
  return folder ? { ...folder } : null;
12620
12632
  }
12621
12633
  function findFolderByName(name) {
12622
12634
  load$1();
12623
12635
  const normalized = name.trim().toLowerCase();
12624
12636
  if (!normalized || normalized === "unsorted") return null;
12625
- const folder = state$1.folders.find(
12637
+ const folder = state$2.folders.find(
12626
12638
  (item) => item.name.trim().toLowerCase() === normalized
12627
12639
  );
12628
12640
  return folder ? { ...folder } : null;
@@ -12630,7 +12642,7 @@ function findFolderByName(name) {
12630
12642
  function listFolderOverviews() {
12631
12643
  load$1();
12632
12644
  const counts = /* @__PURE__ */ new Map();
12633
- for (const bookmark of state$1.bookmarks) {
12645
+ for (const bookmark of state$2.bookmarks) {
12634
12646
  counts.set(bookmark.folderId, (counts.get(bookmark.folderId) ?? 0) + 1);
12635
12647
  }
12636
12648
  return [
@@ -12639,7 +12651,7 @@ function listFolderOverviews() {
12639
12651
  name: "Unsorted",
12640
12652
  count: counts.get(UNSORTED_ID) ?? 0
12641
12653
  },
12642
- ...state$1.folders.map((folder) => ({
12654
+ ...state$2.folders.map((folder) => ({
12643
12655
  id: folder.id,
12644
12656
  name: folder.name,
12645
12657
  summary: folder.summary,
@@ -12650,8 +12662,8 @@ function listFolderOverviews() {
12650
12662
  function searchBookmarks(query) {
12651
12663
  load$1();
12652
12664
  if (!query.trim()) return [];
12653
- return state$1.bookmarks.map((bookmark) => {
12654
- const folder = state$1.folders.find(
12665
+ return state$2.bookmarks.map((bookmark) => {
12666
+ const folder = state$2.folders.find(
12655
12667
  (item) => item.id === bookmark.folderId
12656
12668
  );
12657
12669
  const { matchedFields, score } = getBookmarkSearchMatch({
@@ -12689,9 +12701,9 @@ function createFolderWithSummary(name, summary) {
12689
12701
  summary: summary?.trim() || void 0,
12690
12702
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
12691
12703
  };
12692
- state$1.folders.push(folder);
12693
- save();
12694
- emit();
12704
+ state$2.folders.push(folder);
12705
+ save$1();
12706
+ emit$2();
12695
12707
  return folder;
12696
12708
  }
12697
12709
  function ensureFolder(name, summary) {
@@ -12720,7 +12732,7 @@ function saveBookmarkWithPolicy(url, title, folderId, note, options) {
12720
12732
  throw new Error("Bookmark URL cannot be empty");
12721
12733
  }
12722
12734
  const normalizedTitle = title.trim() || normalizedUrl;
12723
- const targetId = folderId && folderId !== UNSORTED_ID ? state$1.folders.find((f) => f.id === folderId)?.id ?? UNSORTED_ID : UNSORTED_ID;
12735
+ const targetId = folderId && folderId !== UNSORTED_ID ? state$2.folders.find((f) => f.id === folderId)?.id ?? UNSORTED_ID : UNSORTED_ID;
12724
12736
  const duplicatePolicy = options?.onDuplicate ?? "ask";
12725
12737
  const existing = getBookmarkByUrlInFolder(normalizedUrl, targetId);
12726
12738
  if (existing) {
@@ -12731,7 +12743,7 @@ function saveBookmarkWithPolicy(url, title, folderId, note, options) {
12731
12743
  };
12732
12744
  }
12733
12745
  if (duplicatePolicy === "update") {
12734
- const bookmark2 = state$1.bookmarks.find((item) => item.id === existing.id);
12746
+ const bookmark2 = state$2.bookmarks.find((item) => item.id === existing.id);
12735
12747
  if (!bookmark2) {
12736
12748
  return {
12737
12749
  status: "conflict",
@@ -12744,8 +12756,8 @@ function saveBookmarkWithPolicy(url, title, folderId, note, options) {
12744
12756
  }
12745
12757
  assignDefinedBookmarkFields(bookmark2, options?.extra);
12746
12758
  bookmark2.savedAt = (/* @__PURE__ */ new Date()).toISOString();
12747
- save();
12748
- emit();
12759
+ save$1();
12760
+ emit$2();
12749
12761
  return {
12750
12762
  status: "updated",
12751
12763
  bookmark: { ...bookmark2 }
@@ -12761,9 +12773,9 @@ function saveBookmarkWithPolicy(url, title, folderId, note, options) {
12761
12773
  savedAt: (/* @__PURE__ */ new Date()).toISOString(),
12762
12774
  ...options?.extra
12763
12775
  };
12764
- state$1.bookmarks.push(bookmark);
12765
- save();
12766
- emit();
12776
+ state$2.bookmarks.push(bookmark);
12777
+ save$1();
12778
+ emit$2();
12767
12779
  return {
12768
12780
  status: "created",
12769
12781
  bookmark
@@ -12771,18 +12783,18 @@ function saveBookmarkWithPolicy(url, title, folderId, note, options) {
12771
12783
  }
12772
12784
  function removeBookmark(id) {
12773
12785
  load$1();
12774
- const before = state$1.bookmarks.length;
12775
- state$1.bookmarks = state$1.bookmarks.filter((b) => b.id !== id);
12776
- if (state$1.bookmarks.length !== before) {
12777
- save();
12778
- emit();
12786
+ const before = state$2.bookmarks.length;
12787
+ state$2.bookmarks = state$2.bookmarks.filter((b) => b.id !== id);
12788
+ if (state$2.bookmarks.length !== before) {
12789
+ save$1();
12790
+ emit$2();
12779
12791
  return true;
12780
12792
  }
12781
12793
  return false;
12782
12794
  }
12783
12795
  function updateBookmark(id, updates) {
12784
12796
  load$1();
12785
- const bookmark = state$1.bookmarks.find((item) => item.id === id);
12797
+ const bookmark = state$2.bookmarks.find((item) => item.id === id);
12786
12798
  if (!bookmark) return null;
12787
12799
  const metadataUpdates = normalizeBookmarkMetadataUpdate({
12788
12800
  intent: updates.intent,
@@ -12799,7 +12811,7 @@ function updateBookmark(id, updates) {
12799
12811
  bookmark.note = trimmed || void 0;
12800
12812
  }
12801
12813
  if (typeof updates.folderId === "string") {
12802
- bookmark.folderId = updates.folderId && updates.folderId !== UNSORTED_ID ? state$1.folders.find((item) => item.id === updates.folderId)?.id ?? UNSORTED_ID : UNSORTED_ID;
12814
+ bookmark.folderId = updates.folderId && updates.folderId !== UNSORTED_ID ? state$2.folders.find((item) => item.id === updates.folderId)?.id ?? UNSORTED_ID : UNSORTED_ID;
12803
12815
  }
12804
12816
  if ("intent" in metadataUpdates) {
12805
12817
  bookmark.intent = metadataUpdates.intent;
@@ -12816,36 +12828,36 @@ function updateBookmark(id, updates) {
12816
12828
  if ("agentHints" in metadataUpdates) {
12817
12829
  bookmark.agentHints = metadataUpdates.agentHints;
12818
12830
  }
12819
- save();
12820
- emit();
12831
+ save$1();
12832
+ emit$2();
12821
12833
  return { ...bookmark };
12822
12834
  }
12823
12835
  function removeFolder(id, deleteContents = false) {
12824
12836
  load$1();
12825
- const exists = state$1.folders.some((f) => f.id === id);
12837
+ const exists = state$2.folders.some((f) => f.id === id);
12826
12838
  if (!exists) return false;
12827
12839
  if (deleteContents) {
12828
- state$1.bookmarks = state$1.bookmarks.filter((b) => b.folderId !== id);
12840
+ state$2.bookmarks = state$2.bookmarks.filter((b) => b.folderId !== id);
12829
12841
  } else {
12830
- state$1.bookmarks = state$1.bookmarks.map(
12842
+ state$2.bookmarks = state$2.bookmarks.map(
12831
12843
  (b) => b.folderId === id ? { ...b, folderId: UNSORTED_ID } : b
12832
12844
  );
12833
12845
  }
12834
- state$1.folders = state$1.folders.filter((f) => f.id !== id);
12835
- save();
12836
- emit();
12846
+ state$2.folders = state$2.folders.filter((f) => f.id !== id);
12847
+ save$1();
12848
+ emit$2();
12837
12849
  return true;
12838
12850
  }
12839
12851
  function renameFolder(id, newName, summary) {
12840
12852
  load$1();
12841
- const folder = state$1.folders.find((f) => f.id === id);
12853
+ const folder = state$2.folders.find((f) => f.id === id);
12842
12854
  if (!folder) return null;
12843
12855
  const trimmed = newName.trim();
12844
12856
  if (!trimmed) return null;
12845
12857
  folder.name = trimmed;
12846
12858
  folder.summary = summary?.trim() || void 0;
12847
- save();
12848
- emit();
12859
+ save$1();
12860
+ emit$2();
12849
12861
  return { ...folder };
12850
12862
  }
12851
12863
  function flushPersist$1() {
@@ -12856,7 +12868,7 @@ function importBookmarksFromHtml(content) {
12856
12868
  let skipped = 0;
12857
12869
  let errors = 0;
12858
12870
  load$1();
12859
- const existingUrls = new Set(state$1.bookmarks.map((b) => b.url));
12871
+ const existingUrls = new Set(state$2.bookmarks.map((b) => b.url));
12860
12872
  let currentFolderId = UNSORTED_ID;
12861
12873
  let currentFolderName = "Imported";
12862
12874
  const lines = content.split("\n");
@@ -12865,7 +12877,7 @@ function importBookmarksFromHtml(content) {
12865
12877
  const folderMatch = line.match(/<DT><H3[^>]*>([^<]+)<\/H3>/i);
12866
12878
  if (folderMatch) {
12867
12879
  currentFolderName = folderMatch[1].trim();
12868
- const existing = state$1.folders.find(
12880
+ const existing = state$2.folders.find(
12869
12881
  (f) => f.name.toLowerCase() === currentFolderName.toLowerCase()
12870
12882
  );
12871
12883
  if (existing) {
@@ -12876,7 +12888,7 @@ function importBookmarksFromHtml(content) {
12876
12888
  name: currentFolderName,
12877
12889
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
12878
12890
  };
12879
- state$1.folders.push(folder);
12891
+ state$2.folders.push(folder);
12880
12892
  currentFolderId = folder.id;
12881
12893
  }
12882
12894
  continue;
@@ -12897,7 +12909,7 @@ function importBookmarksFromHtml(content) {
12897
12909
  else errors++;
12898
12910
  continue;
12899
12911
  }
12900
- state$1.bookmarks.push({
12912
+ state$2.bookmarks.push({
12901
12913
  id: crypto$1.randomUUID(),
12902
12914
  url,
12903
12915
  title,
@@ -12909,8 +12921,8 @@ function importBookmarksFromHtml(content) {
12909
12921
  }
12910
12922
  }
12911
12923
  if (imported > 0) {
12912
- save();
12913
- emit();
12924
+ save$1();
12925
+ emit$2();
12914
12926
  }
12915
12927
  return { imported, skipped, errors };
12916
12928
  }
@@ -12923,14 +12935,14 @@ function importBookmarksFromJson(content) {
12923
12935
  const incomingFolders = Array.isArray(parsed?.folders) ? parsed.folders : [];
12924
12936
  const incomingBookmarks = Array.isArray(parsed?.bookmarks) ? parsed.bookmarks : [];
12925
12937
  load$1();
12926
- const existingUrls = new Set(state$1.bookmarks.map((b) => b.url));
12938
+ const existingUrls = new Set(state$2.bookmarks.map((b) => b.url));
12927
12939
  const folderIdMap = /* @__PURE__ */ new Map();
12928
12940
  for (const folder of incomingFolders) {
12929
12941
  if (!folder?.id || !folder?.name) {
12930
12942
  errors++;
12931
12943
  continue;
12932
12944
  }
12933
- const existing = state$1.folders.find(
12945
+ const existing = state$2.folders.find(
12934
12946
  (f) => f.name.toLowerCase() === folder.name.toLowerCase()
12935
12947
  );
12936
12948
  if (existing) {
@@ -12942,7 +12954,7 @@ function importBookmarksFromJson(content) {
12942
12954
  summary: folder.summary?.trim() || void 0,
12943
12955
  createdAt: folder.createdAt || (/* @__PURE__ */ new Date()).toISOString()
12944
12956
  };
12945
- state$1.folders.push(newFolder);
12957
+ state$2.folders.push(newFolder);
12946
12958
  folderIdMap.set(folder.id, newFolder.id);
12947
12959
  }
12948
12960
  }
@@ -12956,7 +12968,7 @@ function importBookmarksFromJson(content) {
12956
12968
  continue;
12957
12969
  }
12958
12970
  const mappedFolderId = bookmark.folderId ? folderIdMap.get(bookmark.folderId) ?? UNSORTED_ID : UNSORTED_ID;
12959
- state$1.bookmarks.push({
12971
+ state$2.bookmarks.push({
12960
12972
  id: crypto$1.randomUUID(),
12961
12973
  url: bookmark.url.trim(),
12962
12974
  title: typeof bookmark.title === "string" ? bookmark.title.trim() : bookmark.url,
@@ -12968,8 +12980,8 @@ function importBookmarksFromJson(content) {
12968
12980
  imported++;
12969
12981
  }
12970
12982
  if (imported > 0 || errors > 0) {
12971
- save();
12972
- emit();
12983
+ save$1();
12984
+ emit$2();
12973
12985
  }
12974
12986
  } catch {
12975
12987
  errors++;
@@ -13013,9 +13025,9 @@ async function captureLiveHighlightSnapshot(wc, savedHighlights = []) {
13013
13025
  text: normalizeText(highlight.text),
13014
13026
  color: highlight.color?.trim() || void 0
13015
13027
  })).filter((highlight) => highlight.text.length > 0).filter((highlight) => {
13016
- const key = `${highlight.text}\0${highlight.color ?? ""}`;
13017
- if (seen.has(key)) return false;
13018
- seen.add(key);
13028
+ const key2 = `${highlight.text}\0${highlight.color ?? ""}`;
13029
+ if (seen.has(key2)) return false;
13030
+ seen.add(key2);
13019
13031
  return true;
13020
13032
  }).map((highlight) => ({
13021
13033
  ...highlight,
@@ -13364,17 +13376,17 @@ function sessionFileName(name) {
13364
13376
  function getSessionPath(name) {
13365
13377
  return path$1.join(ensureSessionsDir(), sessionFileName(name));
13366
13378
  }
13367
- function writeSessionFile(filePath, data) {
13379
+ function writeSessionFile(filePath2, data) {
13368
13380
  fs$1.writeFileSync(
13369
- filePath,
13381
+ filePath2,
13370
13382
  JSON.stringify({ version: SESSION_VERSION, ...data }, null, 2),
13371
13383
  { encoding: "utf-8", mode: 384 }
13372
13384
  );
13373
- fs$1.chmodSync(filePath, 384);
13385
+ fs$1.chmodSync(filePath2, 384);
13374
13386
  }
13375
- function readSessionFile(filePath) {
13387
+ function readSessionFile(filePath2) {
13376
13388
  try {
13377
- const raw = fs$1.readFileSync(filePath, "utf-8");
13389
+ const raw = fs$1.readFileSync(filePath2, "utf-8");
13378
13390
  const parsed = JSON.parse(raw);
13379
13391
  if (!parsed || typeof parsed.name !== "string") {
13380
13392
  return null;
@@ -13595,9 +13607,9 @@ async function loadNamedSession(tabManager, name) {
13595
13607
  };
13596
13608
  }
13597
13609
  function deleteNamedSession(name) {
13598
- const filePath = getSessionPath(name);
13599
- if (!fs$1.existsSync(filePath)) return false;
13600
- fs$1.unlinkSync(filePath);
13610
+ const filePath2 = getSessionPath(name);
13611
+ if (!fs$1.existsSync(filePath2)) return false;
13612
+ fs$1.unlinkSync(filePath2);
13601
13613
  return true;
13602
13614
  }
13603
13615
  function isInvalidTextTargetQuery(rawQuery) {
@@ -15054,9 +15066,9 @@ function isAddToCartText(text) {
15054
15066
  }
15055
15067
  function recordCartClick(url, text) {
15056
15068
  recentCartClicks.set(url, { text, ts: Date.now() });
15057
- for (const [key, entry] of recentCartClicks) {
15069
+ for (const [key2, entry] of recentCartClicks) {
15058
15070
  if (Date.now() - entry.ts > CART_CLICK_COOLDOWN_MS) {
15059
- recentCartClicks.delete(key);
15071
+ recentCartClicks.delete(key2);
15060
15072
  }
15061
15073
  }
15062
15074
  }
@@ -15103,9 +15115,9 @@ function normalizeCartProductKey(url) {
15103
15115
  }
15104
15116
  }
15105
15117
  function pruneCartAddedProducts(now = Date.now()) {
15106
- for (const [key, entry] of cartAddedProducts) {
15118
+ for (const [key2, entry] of cartAddedProducts) {
15107
15119
  if (now - entry.ts > CART_ADDED_TTL_MS) {
15108
- cartAddedProducts.delete(key);
15120
+ cartAddedProducts.delete(key2);
15109
15121
  }
15110
15122
  }
15111
15123
  }
@@ -15131,7 +15143,7 @@ function isProductAlreadyInCart(url) {
15131
15143
  function getCartAddedSummary(url) {
15132
15144
  pruneCartAddedProducts();
15133
15145
  const origin = cartOrigin(url);
15134
- const items = Array.from(cartAddedProducts.entries()).filter(([key]) => !origin || key.startsWith(`${origin}/`)).map(([_path, info]) => `- ${info.title}`).join("\n");
15146
+ const items = Array.from(cartAddedProducts.entries()).filter(([key2]) => !origin || key2.startsWith(`${origin}/`)).map(([_path, info]) => `- ${info.title}`).join("\n");
15135
15147
  if (!items) return "";
15136
15148
  const count = items.split("\n").length;
15137
15149
  return `
@@ -16787,8 +16799,8 @@ async function submitForm(wc, args) {
16787
16799
  }
16788
16800
  return "Submitted form";
16789
16801
  }
16790
- async function pressKeyDirect(wc, key, index, selector) {
16791
- return pressKey(wc, { key, index, selector });
16802
+ async function pressKeyDirect(wc, key2, index, selector) {
16803
+ return pressKey(wc, { key: key2, index, selector });
16792
16804
  }
16793
16805
  async function submitFormDirect(wc, index, selector) {
16794
16806
  return submitForm(wc, { index, selector });
@@ -17154,8 +17166,8 @@ async function searchPage(wc, args) {
17154
17166
  return `Searched "${query}" (same page — results may have loaded dynamically)${await getPostSearchSummary(wc)}`;
17155
17167
  }
17156
17168
  async function pressKey(wc, args) {
17157
- const key = typeof args.key === "string" ? args.key.trim() : "";
17158
- if (!key) return "Error: No key provided";
17169
+ const key2 = typeof args.key === "string" ? args.key.trim() : "";
17170
+ if (!key2) return "Error: No key provided";
17159
17171
  const selector = await resolveSelector(wc, args.index, args.selector);
17160
17172
  const focusResult = await executePageScript(
17161
17173
  wc,
@@ -17193,16 +17205,16 @@ async function pressKey(wc, args) {
17193
17205
  return focusResult.error;
17194
17206
  }
17195
17207
  wc.focus();
17196
- const normalizedKey = key.length === 1 ? key : key[0].toUpperCase() + key.slice(1);
17208
+ const normalizedKey = key2.length === 1 ? key2 : key2[0].toUpperCase() + key2.slice(1);
17197
17209
  const electronKeyCode = normalizedKey === "Enter" ? "Return" : normalizedKey === "ArrowUp" ? "Up" : normalizedKey === "ArrowDown" ? "Down" : normalizedKey === "ArrowLeft" ? "Left" : normalizedKey === "ArrowRight" ? "Right" : normalizedKey;
17198
17210
  wc.sendInputEvent({ type: "keyDown", keyCode: electronKeyCode });
17199
- if (key.length === 1) {
17200
- wc.sendInputEvent({ type: "char", keyCode: key });
17211
+ if (key2.length === 1) {
17212
+ wc.sendInputEvent({ type: "char", keyCode: key2 });
17201
17213
  }
17202
17214
  await sleep(16);
17203
17215
  wc.sendInputEvent({ type: "keyUp", keyCode: electronKeyCode });
17204
17216
  const label = "label" in focusResult && typeof focusResult.label === "string" ? focusResult.label : null;
17205
- return label ? `Pressed key: ${key} on ${label}` : `Pressed key: ${key}`;
17217
+ return label ? `Pressed key: ${key2} on ${label}` : `Pressed key: ${key2}`;
17206
17218
  }
17207
17219
  async function getPostActionState$1(ctx, name) {
17208
17220
  const tab = ctx.tabManager.getActiveTab();
@@ -17612,8 +17624,8 @@ async function executeAction(name, args, ctx) {
17612
17624
  if (!wc) return "Error: No active tab";
17613
17625
  const beforeUrl = wc.getURL();
17614
17626
  const result2 = await pressKey(wc, args);
17615
- const key = typeof args.key === "string" ? args.key.trim() : "";
17616
- if (key === "Enter") {
17627
+ const key2 = typeof args.key === "string" ? args.key.trim() : "";
17628
+ if (key2 === "Enter") {
17617
17629
  await waitForPotentialNavigation(wc, beforeUrl, 3e3);
17618
17630
  const afterUrl = wc.getURL();
17619
17631
  if (afterUrl !== beforeUrl) {
@@ -18718,17 +18730,17 @@ function escapeYaml(value) {
18718
18730
  }
18719
18731
  function renderFrontmatter(data) {
18720
18732
  const lines = ["---"];
18721
- for (const [key, value] of Object.entries(data)) {
18733
+ for (const [key2, value] of Object.entries(data)) {
18722
18734
  if (value == null) continue;
18723
18735
  if (Array.isArray(value)) {
18724
18736
  if (value.length === 0) continue;
18725
- lines.push(`${key}:`);
18737
+ lines.push(`${key2}:`);
18726
18738
  for (const item of value) {
18727
18739
  lines.push(` - ${escapeYaml(item)}`);
18728
18740
  }
18729
18741
  continue;
18730
18742
  }
18731
- lines.push(`${key}: ${escapeYaml(value)}`);
18743
+ lines.push(`${key2}: ${escapeYaml(value)}`);
18732
18744
  }
18733
18745
  lines.push("---", "");
18734
18746
  return lines.join("\n");
@@ -18781,11 +18793,11 @@ function parseFrontmatter(content) {
18781
18793
  activeArrayKey = "";
18782
18794
  const separatorIndex = trimmed.indexOf(":");
18783
18795
  if (separatorIndex === -1) continue;
18784
- const key = trimmed.slice(0, separatorIndex).trim();
18796
+ const key2 = trimmed.slice(0, separatorIndex).trim();
18785
18797
  const value = trimmed.slice(separatorIndex + 1).trim();
18786
- if (key === "title" && value) {
18798
+ if (key2 === "title" && value) {
18787
18799
  result.title = value.replace(/^["']|["']$/g, "");
18788
- } else if (key === "tags") {
18800
+ } else if (key2 === "tags") {
18789
18801
  activeArrayKey = "tags";
18790
18802
  if (value.startsWith("[") && value.endsWith("]")) {
18791
18803
  const inline = value.slice(1, -1).split(",").map((item) => item.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
@@ -19371,15 +19383,15 @@ Exception: ${result.exceptionDetails}`);
19371
19383
  value: zod.z.string().nullable().describe("Value to set, or null to remove the key")
19372
19384
  }
19373
19385
  },
19374
- async ({ type, key, value }) => {
19386
+ async ({ type, key: key2, value }) => {
19375
19387
  return withDevToolsAction(
19376
19388
  runtime2,
19377
19389
  tabManager,
19378
19390
  "devtools_set_storage",
19379
- { type, key, value: value ? value.slice(0, 100) : null },
19391
+ { type, key: key2, value: value ? value.slice(0, 100) : null },
19380
19392
  async () => {
19381
19393
  const session = getOrCreateSession(tabManager);
19382
- return session.setStorage(type, key, value);
19394
+ return session.setStorage(type, key2, value);
19383
19395
  }
19384
19396
  );
19385
19397
  }
@@ -19471,11 +19483,11 @@ function getOrCreateEncryptionKey(keyFilename) {
19471
19483
  const encryptedKey = fs$1.readFileSync(keyPath);
19472
19484
  return Buffer.from(electron.safeStorage.decryptString(encryptedKey), "utf-8");
19473
19485
  }
19474
- const key = crypto$2.randomBytes(32);
19486
+ const key2 = crypto$2.randomBytes(32);
19475
19487
  fs$1.mkdirSync(path$1.dirname(keyPath), { recursive: true });
19476
- const encrypted = electron.safeStorage.encryptString(key.toString("utf-8"));
19488
+ const encrypted = electron.safeStorage.encryptString(key2.toString("utf-8"));
19477
19489
  fs$1.writeFileSync(keyPath, encrypted, { mode: 384 });
19478
- return key;
19490
+ return key2;
19479
19491
  }
19480
19492
  function createEncryptDecrypt(keyFilename) {
19481
19493
  let cachedKey = null;
@@ -19484,9 +19496,9 @@ function createEncryptDecrypt(keyFilename) {
19484
19496
  return cachedKey;
19485
19497
  }
19486
19498
  function encrypt2(plaintext) {
19487
- const key = getKey();
19499
+ const key2 = getKey();
19488
19500
  const iv = crypto$2.randomBytes(IV_LENGTH);
19489
- const cipher = crypto$2.createCipheriv(ALGORITHM, key, iv, {
19501
+ const cipher = crypto$2.createCipheriv(ALGORITHM, key2, iv, {
19490
19502
  authTagLength: AUTH_TAG_LENGTH
19491
19503
  });
19492
19504
  const encrypted = Buffer.concat([
@@ -19497,11 +19509,11 @@ function createEncryptDecrypt(keyFilename) {
19497
19509
  return Buffer.concat([iv, authTag, encrypted]);
19498
19510
  }
19499
19511
  function decrypt2(data) {
19500
- const key = getKey();
19512
+ const key2 = getKey();
19501
19513
  const iv = data.subarray(0, IV_LENGTH);
19502
19514
  const authTag = data.subarray(IV_LENGTH, IV_LENGTH + AUTH_TAG_LENGTH);
19503
19515
  const ciphertext = data.subarray(IV_LENGTH + AUTH_TAG_LENGTH);
19504
- const decipher = crypto$2.createDecipheriv(ALGORITHM, key, iv, {
19516
+ const decipher = crypto$2.createDecipheriv(ALGORITHM, key2, iv, {
19505
19517
  authTagLength: AUTH_TAG_LENGTH
19506
19518
  });
19507
19519
  decipher.setAuthTag(authTag);
@@ -19938,10 +19950,10 @@ function getPersistentMcpAuthToken() {
19938
19950
  }
19939
19951
  function writeMcpAuthFile(endpoint, token) {
19940
19952
  try {
19941
- const filePath = getMcpAuthFilePath();
19942
- fs$1.mkdirSync(path$1.dirname(filePath), { recursive: true });
19953
+ const filePath2 = getMcpAuthFilePath();
19954
+ fs$1.mkdirSync(path$1.dirname(filePath2), { recursive: true });
19943
19955
  fs$1.writeFileSync(
19944
- filePath,
19956
+ filePath2,
19945
19957
  JSON.stringify({ endpoint, token, pid: process.pid }, null, 2) + "\n",
19946
19958
  { mode: 384 }
19947
19959
  );
@@ -19959,10 +19971,10 @@ function clearMcpAuthFile() {
19959
19971
  return;
19960
19972
  }
19961
19973
  try {
19962
- const filePath = getMcpAuthFilePath();
19963
- fs$1.mkdirSync(path$1.dirname(filePath), { recursive: true });
19974
+ const filePath2 = getMcpAuthFilePath();
19975
+ fs$1.mkdirSync(path$1.dirname(filePath2), { recursive: true });
19964
19976
  fs$1.writeFileSync(
19965
- filePath,
19977
+ filePath2,
19966
19978
  JSON.stringify(
19967
19979
  { endpoint: "", token: existingToken, pid: null },
19968
19980
  null,
@@ -20978,19 +20990,19 @@ ${buildScopedContext(pageContent, mode)}`;
20978
20990
  selector: zod.z.string().optional().describe("CSS selector to focus first")
20979
20991
  }
20980
20992
  },
20981
- async ({ key, index, selector }) => {
20993
+ async ({ key: key2, index, selector }) => {
20982
20994
  const tab = tabManager.getActiveTab();
20983
20995
  if (!tab) return asNoActiveTabResponse();
20984
20996
  return withAction(
20985
20997
  runtime2,
20986
20998
  tabManager,
20987
20999
  "press_key",
20988
- { key, index, selector },
21000
+ { key: key2, index, selector },
20989
21001
  async () => {
20990
21002
  const wc = tab.view.webContents;
20991
21003
  const beforeUrl = wc.getURL();
20992
- const result = await pressKeyDirect(wc, key, index, selector);
20993
- if (key === "Enter") {
21004
+ const result = await pressKeyDirect(wc, key2, index, selector);
21005
+ if (key2 === "Enter") {
20994
21006
  await waitForPotentialNavigation$1(wc, beforeUrl, 3e3);
20995
21007
  const afterUrl = wc.getURL();
20996
21008
  if (afterUrl !== beforeUrl) {
@@ -21456,7 +21468,7 @@ To analyze visually, call vision_analyze with image_url="${screenshotPath}"`
21456
21468
  )
21457
21469
  }
21458
21470
  },
21459
- async ({ index, selector, text, label, durationMs, persist, color }) => {
21471
+ async ({ index, selector, text, label, durationMs, persist: persist2, color }) => {
21460
21472
  const tab = tabManager.getActiveTab();
21461
21473
  if (!tab) return asNoActiveTabResponse();
21462
21474
  const normalizedText = normalizeLooseString(text);
@@ -21470,7 +21482,7 @@ To analyze visually, call vision_analyze with image_url="${screenshotPath}"`
21470
21482
  text: normalizedText,
21471
21483
  label,
21472
21484
  durationMs,
21473
- persist,
21485
+ persist: persist2,
21474
21486
  color
21475
21487
  },
21476
21488
  async () => {
@@ -21484,7 +21496,7 @@ To analyze visually, call vision_analyze with image_url="${screenshotPath}"`
21484
21496
  durationMs,
21485
21497
  color
21486
21498
  );
21487
- if (persist && !durationMs && !result.startsWith("Error") && !result.includes("not found")) {
21499
+ if (persist2 && !durationMs && !result.startsWith("Error") && !result.includes("not found")) {
21488
21500
  const url = normalizeUrl$1(wc.getURL());
21489
21501
  addHighlight(
21490
21502
  url,
@@ -24149,7 +24161,7 @@ const PROFILE_FIELDS = [
24149
24161
  "postalCode",
24150
24162
  "country"
24151
24163
  ];
24152
- let state = null;
24164
+ let state$1 = null;
24153
24165
  function getFilePath() {
24154
24166
  return path.join(electron.app.getPath("userData"), "vessel-autofill.json");
24155
24167
  }
@@ -24174,8 +24186,8 @@ function normalizeStoredProfile(value) {
24174
24186
  return profile;
24175
24187
  }
24176
24188
  function load() {
24177
- if (state) return state;
24178
- state = loadJsonFile({
24189
+ if (state$1) return state$1;
24190
+ state$1 = loadJsonFile({
24179
24191
  filePath: getFilePath(),
24180
24192
  fallback: getDefaultState(),
24181
24193
  secure: true,
@@ -24186,12 +24198,12 @@ function load() {
24186
24198
  };
24187
24199
  }
24188
24200
  });
24189
- return state;
24201
+ return state$1;
24190
24202
  }
24191
- const persistence = createDebouncedJsonPersistence({
24203
+ const persistence$2 = createDebouncedJsonPersistence({
24192
24204
  debounceMs: SAVE_DEBOUNCE_MS,
24193
24205
  filePath: getFilePath(),
24194
- getValue: () => state,
24206
+ getValue: () => state$1,
24195
24207
  logLabel: "autofill",
24196
24208
  secure: true
24197
24209
  });
@@ -24211,7 +24223,7 @@ function addProfile(input) {
24211
24223
  updatedAt: now
24212
24224
  };
24213
24225
  s.profiles.push(profile);
24214
- persistence.schedule();
24226
+ persistence$2.schedule();
24215
24227
  return profile;
24216
24228
  }
24217
24229
  function updateProfile(id, updates) {
@@ -24223,7 +24235,7 @@ function updateProfile(id, updates) {
24223
24235
  ...updates,
24224
24236
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
24225
24237
  };
24226
- persistence.schedule();
24238
+ persistence$2.schedule();
24227
24239
  return s.profiles[idx];
24228
24240
  }
24229
24241
  function deleteProfile(id) {
@@ -24231,11 +24243,11 @@ function deleteProfile(id) {
24231
24243
  const len = s.profiles.length;
24232
24244
  s.profiles = s.profiles.filter((p) => p.id !== id);
24233
24245
  if (s.profiles.length === len) return false;
24234
- persistence.schedule();
24246
+ persistence$2.schedule();
24235
24247
  return true;
24236
24248
  }
24237
24249
  function flushPersist() {
24238
- return persistence.flush();
24250
+ return persistence$2.flush();
24239
24251
  }
24240
24252
  const AUTOCOMPLETE_MAP = {
24241
24253
  "given-name": "firstName",
@@ -24364,12 +24376,12 @@ function matchField(el, profile) {
24364
24376
  if (inputType === "hidden" || inputType === "submit" || inputType === "button" || inputType === "file" || inputType === "image") return null;
24365
24377
  if (inputType === "password" || inputType === "checkbox" || inputType === "radio") return null;
24366
24378
  if (el.autocomplete) {
24367
- const key = el.autocomplete.replace(/section-\w+\s+/, "").replace(/^shipping\s+|^billing\s+/, "");
24368
- if (key === "name" || key === "additional-name") {
24379
+ const key2 = el.autocomplete.replace(/section-\w+\s+/, "").replace(/^shipping\s+|^billing\s+/, "");
24380
+ if (key2 === "name" || key2 === "additional-name") {
24369
24381
  const fullName = getFullName(profile);
24370
24382
  if (fullName) return mk(fullName, 100, "autocomplete", "fullName");
24371
24383
  }
24372
- const pk = AUTOCOMPLETE_MAP[key];
24384
+ const pk = AUTOCOMPLETE_MAP[key2];
24373
24385
  if (pk && profile[pk]) return mk(profile[pk], 100, "autocomplete", pk);
24374
24386
  }
24375
24387
  if (INPUT_TYPE_MAP[inputType]) {
@@ -24857,6 +24869,64 @@ function installAdBlockingForSession(ses, tabManager) {
24857
24869
  callback(getAdBlockDecision(details));
24858
24870
  });
24859
24871
  }
24872
+ const filePath$1 = () => path$1.join(electron.app.getPath("userData"), "vessel-downloads.json");
24873
+ function parse(raw) {
24874
+ if (!raw || typeof raw !== "object") return { items: [] };
24875
+ const items = Array.isArray(raw.items) ? raw.items : [];
24876
+ return { items };
24877
+ }
24878
+ let state = loadJsonFile({ filePath: filePath$1(), fallback: { items: [] }, parse });
24879
+ const persistence$1 = createDebouncedJsonPersistence({
24880
+ debounceMs: 250,
24881
+ filePath: filePath$1(),
24882
+ getValue: () => state,
24883
+ logLabel: "downloads"
24884
+ });
24885
+ let broadcaster$1 = null;
24886
+ function persist() {
24887
+ state.items = state.items.slice(0, 200);
24888
+ persistence$1.schedule();
24889
+ }
24890
+ function emit$1() {
24891
+ broadcaster$1?.(Channels.DOWNLOADS_UPDATE, state.items);
24892
+ }
24893
+ function setDownloadBroadcaster(fn) {
24894
+ broadcaster$1 = fn;
24895
+ }
24896
+ function listDownloads() {
24897
+ return state.items;
24898
+ }
24899
+ function upsertDownload(input) {
24900
+ const now = (/* @__PURE__ */ new Date()).toISOString();
24901
+ const existing = state.items.find((item) => item.savePath === input.savePath);
24902
+ if (existing) {
24903
+ Object.assign(existing, input, { updatedAt: now });
24904
+ persist();
24905
+ emit$1();
24906
+ return existing;
24907
+ }
24908
+ const record = { id: crypto$2.randomUUID(), ...input, startedAt: now, updatedAt: now };
24909
+ state.items = [record, ...state.items];
24910
+ persist();
24911
+ emit$1();
24912
+ return record;
24913
+ }
24914
+ function clearDownloads() {
24915
+ state.items = [];
24916
+ persist();
24917
+ emit$1();
24918
+ }
24919
+ async function openDownload(id) {
24920
+ const item = state.items.find((d) => d.id === id);
24921
+ if (!item || !fs$1.existsSync(item.savePath)) return false;
24922
+ return await electron.shell.openPath(item.savePath) === "";
24923
+ }
24924
+ async function showDownloadInFolder(id) {
24925
+ const item = state.items.find((d) => d.id === id);
24926
+ if (!item || !fs$1.existsSync(item.savePath)) return false;
24927
+ electron.shell.showItemInFolder(item.savePath);
24928
+ return true;
24929
+ }
24860
24930
  const defaultDownloadViews = /* @__PURE__ */ new Set();
24861
24931
  let defaultDownloadHandlerInstalled = false;
24862
24932
  function resolveDownloadPath(downloadDir, filename) {
@@ -24903,17 +24973,20 @@ function installDownloadHandlerForSession(targetSession, chromeView) {
24903
24973
  receivedBytes: 0,
24904
24974
  state: "progressing"
24905
24975
  };
24906
- send(Channels.DOWNLOAD_STARTED, info);
24976
+ const record = upsertDownload(info);
24977
+ send(Channels.DOWNLOAD_STARTED, { ...info, id: record.id, startedAt: record.startedAt, updatedAt: record.updatedAt });
24907
24978
  item.on("updated", (_event2, state2) => {
24908
24979
  info.receivedBytes = item.getReceivedBytes();
24909
24980
  info.totalBytes = item.getTotalBytes();
24910
24981
  info.state = state2 === "progressing" ? "progressing" : "interrupted";
24911
- send(Channels.DOWNLOAD_PROGRESS, info);
24982
+ const record2 = upsertDownload(info);
24983
+ send(Channels.DOWNLOAD_PROGRESS, { ...info, id: record2.id, startedAt: record2.startedAt, updatedAt: record2.updatedAt });
24912
24984
  });
24913
24985
  item.once("done", (_event2, state2) => {
24914
24986
  info.receivedBytes = item.getReceivedBytes();
24915
24987
  info.state = state2 === "completed" ? "completed" : "cancelled";
24916
- send(Channels.DOWNLOAD_DONE, info);
24988
+ const record2 = upsertDownload(info);
24989
+ send(Channels.DOWNLOAD_DONE, { ...info, id: record2.id, startedAt: record2.startedAt, updatedAt: record2.updatedAt });
24917
24990
  });
24918
24991
  });
24919
24992
  }
@@ -25627,35 +25700,35 @@ function registerBookmarkHandlers() {
25627
25700
  electron.ipcMain.handle(
25628
25701
  Channels.BOOKMARKS_EXPORT_HTML,
25629
25702
  async (_, options) => {
25630
- const { canceled, filePath } = await electron.dialog.showSaveDialog({
25703
+ const { canceled, filePath: filePath2 } = await electron.dialog.showSaveDialog({
25631
25704
  title: "Export Bookmarks",
25632
25705
  defaultPath: "vessel-bookmarks.html",
25633
25706
  filters: [{ name: "HTML Bookmarks", extensions: ["html"] }]
25634
25707
  });
25635
- if (canceled || !filePath) return null;
25708
+ if (canceled || !filePath2) return null;
25636
25709
  const content = exportBookmarksHtml({
25637
25710
  includeNotes: options?.includeNotes ?? false
25638
25711
  });
25639
- await fs.promises.writeFile(filePath, content, "utf-8");
25712
+ await fs.promises.writeFile(filePath2, content, "utf-8");
25640
25713
  trackBookmarkAction("export");
25641
25714
  return {
25642
- filePath,
25715
+ filePath: filePath2,
25643
25716
  count: getState().bookmarks.length
25644
25717
  };
25645
25718
  }
25646
25719
  );
25647
25720
  electron.ipcMain.handle(Channels.BOOKMARKS_EXPORT_JSON, async () => {
25648
- const { canceled, filePath } = await electron.dialog.showSaveDialog({
25721
+ const { canceled, filePath: filePath2 } = await electron.dialog.showSaveDialog({
25649
25722
  title: "Export Vessel Bookmark Archive",
25650
25723
  defaultPath: "vessel-bookmarks.json",
25651
25724
  filters: [{ name: "Vessel Bookmark Archive", extensions: ["json"] }]
25652
25725
  });
25653
- if (canceled || !filePath) return null;
25726
+ if (canceled || !filePath2) return null;
25654
25727
  const content = exportBookmarksJson();
25655
- await fs.promises.writeFile(filePath, content, "utf-8");
25728
+ await fs.promises.writeFile(filePath2, content, "utf-8");
25656
25729
  trackBookmarkAction("export");
25657
25730
  return {
25658
- filePath,
25731
+ filePath: filePath2,
25659
25732
  count: getState().bookmarks.length
25660
25733
  };
25661
25734
  });
@@ -25664,20 +25737,20 @@ function registerBookmarkHandlers() {
25664
25737
  async (_, folderId, options) => {
25665
25738
  const folder = getFolder(folderId);
25666
25739
  if (!folder) return null;
25667
- const { canceled, filePath } = await electron.dialog.showSaveDialog({
25740
+ const { canceled, filePath: filePath2 } = await electron.dialog.showSaveDialog({
25668
25741
  title: `Export ${folder.name}`,
25669
25742
  defaultPath: `vessel-bookmarks-${getSafeBookmarkExportName(folder.name)}.html`,
25670
25743
  filters: [{ name: "HTML Bookmarks", extensions: ["html"] }]
25671
25744
  });
25672
- if (canceled || !filePath) return null;
25745
+ if (canceled || !filePath2) return null;
25673
25746
  const result = exportBookmarkFolderHtml(folderId, {
25674
25747
  includeNotes: options?.includeNotes ?? true
25675
25748
  });
25676
25749
  if (!result) return null;
25677
- await fs.promises.writeFile(filePath, result.content, "utf-8");
25750
+ await fs.promises.writeFile(filePath2, result.content, "utf-8");
25678
25751
  trackBookmarkAction("export");
25679
25752
  return {
25680
- filePath,
25753
+ filePath: filePath2,
25681
25754
  count: result.count
25682
25755
  };
25683
25756
  }
@@ -25730,26 +25803,26 @@ function registerHistoryHandlers() {
25730
25803
  clearAll$1();
25731
25804
  });
25732
25805
  electron.ipcMain.handle(Channels.HISTORY_EXPORT_HTML, async () => {
25733
- const { canceled, filePath } = await electron.dialog.showSaveDialog({
25806
+ const { canceled, filePath: filePath2 } = await electron.dialog.showSaveDialog({
25734
25807
  title: "Export History",
25735
25808
  defaultPath: "vessel-history.html",
25736
25809
  filters: [{ name: "HTML", extensions: ["html"] }]
25737
25810
  });
25738
- if (canceled || !filePath) return null;
25811
+ if (canceled || !filePath2) return null;
25739
25812
  const content = exportHistoryHtml();
25740
- await fs.promises.writeFile(filePath, content, "utf-8");
25741
- return { filePath, count: getState$1().entries.length };
25813
+ await fs.promises.writeFile(filePath2, content, "utf-8");
25814
+ return { filePath: filePath2, count: getState$1().entries.length };
25742
25815
  });
25743
25816
  electron.ipcMain.handle(Channels.HISTORY_EXPORT_JSON, async () => {
25744
- const { canceled, filePath } = await electron.dialog.showSaveDialog({
25817
+ const { canceled, filePath: filePath2 } = await electron.dialog.showSaveDialog({
25745
25818
  title: "Export History",
25746
25819
  defaultPath: "vessel-history.json",
25747
25820
  filters: [{ name: "JSON", extensions: ["json"] }]
25748
25821
  });
25749
- if (canceled || !filePath) return null;
25822
+ if (canceled || !filePath2) return null;
25750
25823
  const content = exportHistoryJson();
25751
- await fs.promises.writeFile(filePath, content, "utf-8");
25752
- return { filePath, count: getState$1().entries.length };
25824
+ await fs.promises.writeFile(filePath2, content, "utf-8");
25825
+ return { filePath: filePath2, count: getState$1().entries.length };
25753
25826
  });
25754
25827
  electron.ipcMain.handle(Channels.HISTORY_IMPORT, async () => {
25755
25828
  const { canceled, filePaths } = await electron.dialog.showOpenDialog({
@@ -25760,9 +25833,9 @@ function registerHistoryHandlers() {
25760
25833
  properties: ["openFile"]
25761
25834
  });
25762
25835
  if (canceled || filePaths.length === 0) return null;
25763
- const filePath = filePaths[0];
25764
- const content = await fs.promises.readFile(filePath, "utf-8");
25765
- const result = filePath.endsWith(".json") ? importHistoryFromJson(content) : importHistoryFromHtml(content);
25836
+ const filePath2 = filePaths[0];
25837
+ const content = await fs.promises.readFile(filePath2, "utf-8");
25838
+ const result = filePath2.endsWith(".json") ? importHistoryFromJson(content) : importHistoryFromHtml(content);
25766
25839
  return result;
25767
25840
  });
25768
25841
  }
@@ -26036,6 +26109,119 @@ function registerCodexHandlers() {
26036
26109
  return { ok: true };
26037
26110
  });
26038
26111
  }
26112
+ const filePath = () => path$1.join(electron.app.getPath("userData"), "vessel-permissions.json");
26113
+ let records = loadJsonFile({
26114
+ filePath: filePath(),
26115
+ fallback: [],
26116
+ parse: (raw) => Array.isArray(raw) ? raw : []
26117
+ });
26118
+ const persistence = createDebouncedJsonPersistence({ debounceMs: 250, filePath: filePath(), getValue: () => records, logLabel: "permissions" });
26119
+ let broadcaster = null;
26120
+ function key(origin, permission) {
26121
+ return `${origin}
26122
+ ${permission}`;
26123
+ }
26124
+ function emit() {
26125
+ broadcaster?.(Channels.PERMISSIONS_GET, records);
26126
+ }
26127
+ function save(origin, permission, decision) {
26128
+ const k = key(origin, permission);
26129
+ const existing = records.find((r) => key(r.origin, r.permission) === k);
26130
+ const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
26131
+ if (existing) Object.assign(existing, { decision, updatedAt });
26132
+ else records.unshift({ origin, permission, decision, updatedAt });
26133
+ persistence.schedule();
26134
+ emit();
26135
+ }
26136
+ function listPermissions() {
26137
+ return records;
26138
+ }
26139
+ function clearPermissions() {
26140
+ records = [];
26141
+ persistence.schedule();
26142
+ emit();
26143
+ }
26144
+ function clearPermissionsForOrigin(origin) {
26145
+ records = records.filter((record) => record.origin !== origin);
26146
+ persistence.schedule();
26147
+ emit();
26148
+ }
26149
+ function setPermissionBroadcaster(fn) {
26150
+ broadcaster = fn;
26151
+ }
26152
+ function installPermissionHandler() {
26153
+ electron.session.defaultSession.setPermissionRequestHandler((webContents, permission, callback, details) => {
26154
+ const origin = new URL(details.requestingUrl || webContents.getURL()).origin;
26155
+ const existing = records.find((r) => r.origin === origin && r.permission === permission);
26156
+ if (existing) {
26157
+ callback(existing.decision === "allow");
26158
+ return;
26159
+ }
26160
+ const result = electron.dialog.showMessageBoxSync({
26161
+ type: "question",
26162
+ buttons: ["Deny", "Allow"],
26163
+ defaultId: 0,
26164
+ cancelId: 0,
26165
+ title: "Site permission request",
26166
+ message: `${origin} wants to use ${permission}`,
26167
+ detail: "Vessel will remember your choice. You can clear saved permissions in Settings > Privacy."
26168
+ });
26169
+ const decision = result === 1 ? "allow" : "deny";
26170
+ save(origin, permission, decision);
26171
+ callback(decision === "allow");
26172
+ });
26173
+ }
26174
+ const NPM_PACKAGE_URL = "https://registry.npmjs.org/@quanta-intellect%2Fvessel-browser/latest";
26175
+ const RELEASES_URL = "https://github.com/unmodeled-tyler/quanta-vessel-browser/releases/latest";
26176
+ function normalizeVersion(version) {
26177
+ return version.replace(/^v/i, "").split(/[.-]/).slice(0, 3).map((part) => {
26178
+ const n = Number.parseInt(part, 10);
26179
+ return Number.isFinite(n) ? n : 0;
26180
+ });
26181
+ }
26182
+ function compareVersions(a, b) {
26183
+ const av = normalizeVersion(a);
26184
+ const bv = normalizeVersion(b);
26185
+ for (let i = 0; i < 3; i += 1) {
26186
+ if ((av[i] ?? 0) > (bv[i] ?? 0)) return 1;
26187
+ if ((av[i] ?? 0) < (bv[i] ?? 0)) return -1;
26188
+ }
26189
+ return 0;
26190
+ }
26191
+ async function checkForUpdates() {
26192
+ const currentVersion = electron.app.getVersion();
26193
+ const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
26194
+ try {
26195
+ const response = await fetch(NPM_PACKAGE_URL, {
26196
+ headers: { accept: "application/json", "user-agent": `Vessel/${currentVersion}` }
26197
+ });
26198
+ if (!response.ok) {
26199
+ throw new Error(`Registry responded with ${response.status}`);
26200
+ }
26201
+ const body = await response.json();
26202
+ const latestVersion = typeof body.version === "string" ? body.version : null;
26203
+ if (!latestVersion) throw new Error("Registry response did not include a version");
26204
+ return {
26205
+ currentVersion,
26206
+ latestVersion,
26207
+ updateAvailable: compareVersions(latestVersion, currentVersion) > 0,
26208
+ checkedAt,
26209
+ releaseUrl: RELEASES_URL
26210
+ };
26211
+ } catch (error) {
26212
+ return {
26213
+ currentVersion,
26214
+ latestVersion: null,
26215
+ updateAvailable: false,
26216
+ checkedAt,
26217
+ releaseUrl: RELEASES_URL,
26218
+ error: error instanceof Error ? error.message : "Update check failed"
26219
+ };
26220
+ }
26221
+ }
26222
+ async function openUpdateDownload() {
26223
+ await electron.shell.openExternal(RELEASES_URL);
26224
+ }
26039
26225
  let activeChatProvider = null;
26040
26226
  const logger$4 = createLogger("IPC");
26041
26227
  const VALID_APPROVAL_MODES = ["auto", "confirm-dangerous", "manual"];
@@ -26433,18 +26619,18 @@ function registerIpcHandlers(windowState, runtime2) {
26433
26619
  return getRendererSettings();
26434
26620
  });
26435
26621
  electron.ipcMain.handle(Channels.SETTINGS_HEALTH_GET, () => getRuntimeHealth());
26436
- electron.ipcMain.handle(Channels.SETTINGS_SET, async (_, key, value) => {
26437
- assertString(key, "key");
26438
- if (!SETTABLE_KEYS.has(key)) {
26439
- throw new Error(`Unknown setting key: ${key}`);
26622
+ electron.ipcMain.handle(Channels.SETTINGS_SET, async (_, key2, value) => {
26623
+ assertString(key2, "key");
26624
+ if (!SETTABLE_KEYS.has(key2)) {
26625
+ throw new Error(`Unknown setting key: ${key2}`);
26440
26626
  }
26441
- const settingsKey = key;
26627
+ const settingsKey = key2;
26442
26628
  const updatedSettings = setSetting(settingsKey, value);
26443
- trackSettingChanged(key);
26444
- if (key === "approvalMode") {
26629
+ trackSettingChanged(key2);
26630
+ if (key2 === "approvalMode") {
26445
26631
  runtime2.setApprovalMode(value);
26446
26632
  }
26447
- if (key === "mcpPort") {
26633
+ if (key2 === "mcpPort") {
26448
26634
  await stopMcpServer();
26449
26635
  await startMcpServer(tabManager, runtime2, updatedSettings.mcpPort);
26450
26636
  }
@@ -26638,6 +26824,26 @@ function registerIpcHandlers(windowState, runtime2) {
26638
26824
  clearByTimeRange(timeRange);
26639
26825
  }
26640
26826
  });
26827
+ setDownloadBroadcaster(sendToRendererViews);
26828
+ setPermissionBroadcaster(sendToRendererViews);
26829
+ electron.ipcMain.handle(Channels.DOWNLOADS_GET, () => listDownloads());
26830
+ electron.ipcMain.handle(Channels.DOWNLOADS_CLEAR, () => {
26831
+ clearDownloads();
26832
+ return true;
26833
+ });
26834
+ electron.ipcMain.handle(Channels.DOWNLOADS_OPEN, (_event, id) => openDownload(id));
26835
+ electron.ipcMain.handle(Channels.DOWNLOADS_SHOW_IN_FOLDER, (_event, id) => showDownloadInFolder(id));
26836
+ electron.ipcMain.handle(Channels.PERMISSIONS_GET, () => listPermissions());
26837
+ electron.ipcMain.handle(Channels.PERMISSIONS_CLEAR, () => {
26838
+ clearPermissions();
26839
+ return true;
26840
+ });
26841
+ electron.ipcMain.handle(Channels.PERMISSIONS_CLEAR_ORIGIN, (_event, origin) => {
26842
+ clearPermissionsForOrigin(origin);
26843
+ return true;
26844
+ });
26845
+ electron.ipcMain.handle(Channels.UPDATES_CHECK, () => checkForUpdates());
26846
+ electron.ipcMain.handle(Channels.UPDATES_OPEN_DOWNLOAD, () => openUpdateDownload());
26641
26847
  electron.ipcMain.handle(Channels.TAB_TOGGLE_PIP, async () => {
26642
26848
  return togglePictureInPicture(tabManager);
26643
26849
  });
@@ -27033,9 +27239,9 @@ function clone(value) {
27033
27239
  function summarizeArgs(args) {
27034
27240
  const entries = Object.entries(args).filter(([, value]) => value != null);
27035
27241
  if (entries.length === 0) return "No arguments";
27036
- return entries.map(([key, value]) => {
27242
+ return entries.map(([key2, value]) => {
27037
27243
  const rendered = typeof value === "string" ? value : JSON.stringify(value);
27038
- return `${key}=${String(rendered).slice(0, 120)}`;
27244
+ return `${key2}=${String(rendered).slice(0, 120)}`;
27039
27245
  }).join(", ");
27040
27246
  }
27041
27247
  function summarizeText(value) {
@@ -28061,6 +28267,7 @@ async function bootstrap() {
28061
28267
  sidebarView.webContents.send(Channels.HISTORY_UPDATE, state2);
28062
28268
  });
28063
28269
  installDownloadHandler(chromeView);
28270
+ installPermissionHandler();
28064
28271
  startBackgroundRevalidation();
28065
28272
  startTelemetry();
28066
28273
  const initializeChromeRenderer = () => {