@quanta-intellect/vessel-browser 0.1.128 → 0.1.130

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
@@ -94,7 +94,7 @@ const defaults = {
94
94
  clearBookmarksOnLaunch: false,
95
95
  obsidianVaultPath: "",
96
96
  approvalMode: "confirm-dangerous",
97
- agentTranscriptMode: "summary",
97
+ agentTranscriptMode: "off",
98
98
  chatProvider: null,
99
99
  maxToolIterations: 200,
100
100
  domainPolicy: { allowedDomains: [], blockedDomains: [] },
@@ -114,7 +114,7 @@ const defaults = {
114
114
  const SAVE_DEBOUNCE_MS$6 = 150;
115
115
  const CHAT_PROVIDER_SECRET_FILENAME = "vessel-chat-provider-secret";
116
116
  const CODEX_TOKENS_FILENAME = "vessel-codex-tokens";
117
- const logger$t = createLogger("Settings");
117
+ const logger$u = createLogger("Settings");
118
118
  const SETTABLE_KEYS = new Set(Object.keys(defaults));
119
119
  let settings = null;
120
120
  let settingsIssues = [];
@@ -139,7 +139,7 @@ function canUseSafeStorage$1() {
139
139
  try {
140
140
  return electron.safeStorage.isEncryptionAvailable();
141
141
  } catch (err) {
142
- logger$t.warn("safeStorage.isEncryptionAvailable() failed, assuming unavailable:", err);
142
+ logger$u.warn("safeStorage.isEncryptionAvailable() failed, assuming unavailable:", err);
143
143
  return false;
144
144
  }
145
145
  }
@@ -148,7 +148,7 @@ function writePrivateFile(filePath2, data) {
148
148
  try {
149
149
  fs.chmodSync(filePath2, 384);
150
150
  } catch (err) {
151
- logger$t.debug("Could not chmod private file (non-POSIX filesystem):", err);
151
+ logger$u.debug("Could not chmod private file (non-POSIX filesystem):", err);
152
152
  }
153
153
  }
154
154
  function assertSafeStorageAvailable() {
@@ -167,7 +167,7 @@ function readStoredProviderSecret() {
167
167
  }
168
168
  } catch (err) {
169
169
  if (!isMissingFileError(err)) {
170
- logger$t.warn("Could not read stored provider secret:", err);
170
+ logger$u.warn("Could not read stored provider secret:", err);
171
171
  }
172
172
  }
173
173
  return null;
@@ -185,7 +185,7 @@ function clearStoredProviderSecret() {
185
185
  fs.unlinkSync(getChatProviderSecretPath());
186
186
  } catch (err) {
187
187
  if (!isMissingFileError(err)) {
188
- logger$t.warn("Could not delete provider secret file:", err);
188
+ logger$u.warn("Could not delete provider secret file:", err);
189
189
  }
190
190
  }
191
191
  }
@@ -203,7 +203,7 @@ function readStoredCodexTokens() {
203
203
  }
204
204
  } catch (err) {
205
205
  if (!isMissingFileError(err)) {
206
- logger$t.warn("Could not read stored Codex tokens:", err);
206
+ logger$u.warn("Could not read stored Codex tokens:", err);
207
207
  }
208
208
  }
209
209
  return null;
@@ -221,7 +221,7 @@ function clearStoredCodexTokens() {
221
221
  fs.unlinkSync(getCodexTokensPath());
222
222
  } catch (err) {
223
223
  if (!isMissingFileError(err)) {
224
- logger$t.warn("Could not delete Codex token file:", err);
224
+ logger$u.warn("Could not delete Codex token file:", err);
225
225
  }
226
226
  }
227
227
  }
@@ -293,6 +293,11 @@ function sanitizeChatProvider(provider) {
293
293
  reasoningEffort: sanitizeReasoningEffortLevel$1(provider.reasoningEffort)
294
294
  } : null;
295
295
  }
296
+ function sanitizeAgentTranscriptMode(mode, legacyEnabled) {
297
+ if (mode === "full") return "full";
298
+ if (mode === "off" || mode === "summary") return "off";
299
+ return legacyEnabled === true ? "full" : "off";
300
+ }
296
301
  function loadSettings() {
297
302
  if (settings) return settings;
298
303
  settingsIssues = [];
@@ -315,7 +320,10 @@ function loadSettings() {
315
320
  sourceDoNotAllowList: sanitizeStringList(
316
321
  parsed.sourceDoNotAllowList ?? defaults.sourceDoNotAllowList
317
322
  ),
318
- agentTranscriptMode: parsed.agentTranscriptMode === "off" || parsed.agentTranscriptMode === "summary" || parsed.agentTranscriptMode === "full" ? parsed.agentTranscriptMode : parsed.showAgentTranscript === false ? "off" : defaults.agentTranscriptMode
323
+ agentTranscriptMode: sanitizeAgentTranscriptMode(
324
+ parsed.agentTranscriptMode,
325
+ parsed.showAgentTranscript
326
+ )
319
327
  };
320
328
  } catch (error) {
321
329
  if (fs.existsSync(getSettingsPath())) {
@@ -343,7 +351,7 @@ function persistNow() {
343
351
  JSON.stringify(buildPersistedSettings(settings), null, 2),
344
352
  { encoding: "utf-8", mode: 384 }
345
353
  )
346
- ).then(() => fs.promises.chmod(getSettingsPath(), 384).catch(() => void 0)).catch((err) => logger$t.error("Failed to save settings:", err));
354
+ ).then(() => fs.promises.chmod(getSettingsPath(), 384).catch(() => void 0)).catch((err) => logger$u.error("Failed to save settings:", err));
347
355
  }
348
356
  function saveSettings() {
349
357
  saveDirty = true;
@@ -522,7 +530,7 @@ const urlSafety = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
522
530
  }, Symbol.toStringTag, { value: "Module" }));
523
531
  const MAX_CUSTOM_HISTORY = 50;
524
532
  const READER_MODE_DATA_URL_PREFIX = "data:text/html;charset=utf-8,";
525
- const logger$s = createLogger("Tab");
533
+ const logger$t = createLogger("Tab");
526
534
  const sessionCertExceptions = /* @__PURE__ */ new WeakMap();
527
535
  const sessionsWithVerifyProc = /* @__PURE__ */ new WeakSet();
528
536
  const CERT_VERIFY_TRUST = 0;
@@ -588,7 +596,7 @@ class Tab {
588
596
  guardedLoadURL(url, options) {
589
597
  const blockReason = this.getNavigationBlockReason(url);
590
598
  if (blockReason) {
591
- logger$s.warn(blockReason);
599
+ logger$t.warn(blockReason);
592
600
  return blockReason;
593
601
  }
594
602
  void this.view.webContents.loadURL(url, options);
@@ -672,7 +680,7 @@ class Tab {
672
680
  wc.setWindowOpenHandler(({ url, disposition }) => {
673
681
  const error = this.getNavigationBlockReason(url);
674
682
  if (error) {
675
- logger$s.warn(error);
683
+ logger$t.warn(error);
676
684
  return { action: "deny" };
677
685
  }
678
686
  this.onOpenUrl?.({
@@ -686,7 +694,7 @@ class Tab {
686
694
  const error = this.getNavigationBlockReason(url);
687
695
  if (!error) return;
688
696
  event.preventDefault();
689
- logger$s.warn(`${context}: ${error}`);
697
+ logger$t.warn(`${context}: ${error}`);
690
698
  };
691
699
  wc.on("will-navigate", (event, url) => {
692
700
  blockNavigation(event, url, "Blocked top-level navigation");
@@ -770,7 +778,7 @@ class Tab {
770
778
  ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 999px; }
771
779
  ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.22); }
772
780
  ::-webkit-scrollbar-corner { background: transparent; }
773
- `).catch((err) => logger$s.warn("Failed to inject scrollbar CSS:", err));
781
+ `).catch((err) => logger$t.warn("Failed to inject scrollbar CSS:", err));
774
782
  });
775
783
  wc.on("page-favicon-updated", (_, favicons) => {
776
784
  this._state.favicon = favicons[0] || "";
@@ -806,7 +814,7 @@ class Tab {
806
814
  ).then((highlightedText) => {
807
815
  this.buildContextMenu(wc, params, highlightedText.trim());
808
816
  }).catch((err) => {
809
- logger$s.warn("Failed to inspect highlighted text for context menu:", err);
817
+ logger$t.warn("Failed to inspect highlighted text for context menu:", err);
810
818
  this.buildContextMenu(wc, params, "");
811
819
  });
812
820
  });
@@ -1007,7 +1015,7 @@ class Tab {
1007
1015
  "document.documentElement.outerHTML"
1008
1016
  );
1009
1017
  } catch (err) {
1010
- logger$s.warn("Failed to retrieve page source:", err);
1018
+ logger$t.warn("Failed to retrieve page source:", err);
1011
1019
  return;
1012
1020
  }
1013
1021
  const escaped = html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -1135,7 +1143,7 @@ class Tab {
1135
1143
  document.addEventListener('mouseup', window.__vesselHighlightHandler);
1136
1144
  }
1137
1145
  })()
1138
- `).catch((err) => logger$s.warn("Failed to inject highlight listener:", err));
1146
+ `).catch((err) => logger$t.warn("Failed to inject highlight listener:", err));
1139
1147
  } else {
1140
1148
  void wc.executeJavaScript(`
1141
1149
  (function() {
@@ -1146,7 +1154,7 @@ class Tab {
1146
1154
  delete window.__vesselHighlightHandler;
1147
1155
  }
1148
1156
  })()
1149
- `).catch((err) => logger$s.warn("Failed to remove highlight listener:", err));
1157
+ `).catch((err) => logger$t.warn("Failed to remove highlight listener:", err));
1150
1158
  }
1151
1159
  }
1152
1160
  get webContentsId() {
@@ -1183,7 +1191,7 @@ const SEARCH_ENGINE_PRESETS = {
1183
1191
  ecosia: { label: "Ecosia", url: "https://www.ecosia.org/search?q=" },
1184
1192
  kagi: { label: "Kagi", url: "https://kagi.com/search?q=" }
1185
1193
  };
1186
- const logger$r = createLogger("JsonPersistence");
1194
+ const logger$s = createLogger("JsonPersistence");
1187
1195
  function canUseSafeStorage() {
1188
1196
  try {
1189
1197
  return electron.safeStorage.isEncryptionAvailable();
@@ -1248,7 +1256,7 @@ function createDebouncedJsonPersistence({
1248
1256
  data,
1249
1257
  typeof data === "string" ? { encoding: "utf-8", mode: 384 } : { mode: 384 }
1250
1258
  )
1251
- ).then(() => fs.promises.chmod(filePath2, 384).catch(() => void 0)).catch((err) => logger$r.error(`Failed to save ${logLabel}:`, err));
1259
+ ).then(() => fs.promises.chmod(filePath2, 384).catch(() => void 0)).catch((err) => logger$s.error(`Failed to save ${logLabel}:`, err));
1252
1260
  };
1253
1261
  const schedule = () => {
1254
1262
  saveDirty2 = true;
@@ -2940,7 +2948,7 @@ function destroySession(tabId) {
2940
2948
  sessions.delete(tabId);
2941
2949
  }
2942
2950
  }
2943
- const logger$q = createLogger("TabManager");
2951
+ const logger$r = createLogger("TabManager");
2944
2952
  function sanitizeFilename(title, ext) {
2945
2953
  const clean = title.replace(/[<>:"/\\|?*\x00-\x1f]/g, " ").replace(/\s+/g, " ").trim();
2946
2954
  const escapedExt = ext.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -3335,7 +3343,7 @@ class TabManager {
3335
3343
  }));
3336
3344
  if (entries.length > 0) {
3337
3345
  void highlightBatchOnPage(wc, entries).catch(
3338
- (err) => logger$q.warn("Failed to batch highlight:", err)
3346
+ (err) => logger$r.warn("Failed to batch highlight:", err)
3339
3347
  );
3340
3348
  }
3341
3349
  }
@@ -3357,12 +3365,12 @@ class TabManager {
3357
3365
  const result = await captureSelectionHighlight(wc);
3358
3366
  if (result.success && result.text) {
3359
3367
  await highlightOnPage(wc, null, result.text, void 0, void 0, "yellow").catch(
3360
- (err) => logger$q.warn("Failed to capture highlight:", err)
3368
+ (err) => logger$r.warn("Failed to capture highlight:", err)
3361
3369
  );
3362
3370
  }
3363
3371
  this.highlightCaptureCallback?.(result);
3364
3372
  } catch (err) {
3365
- logger$q.warn("Failed to capture highlight from page:", err);
3373
+ logger$r.warn("Failed to capture highlight from page:", err);
3366
3374
  this.highlightCaptureCallback?.({
3367
3375
  success: false,
3368
3376
  message: "Could not capture selection"
@@ -3387,7 +3395,7 @@ class TabManager {
3387
3395
  void this.removeHighlightMarksForText(wc, text);
3388
3396
  }
3389
3397
  } catch (err) {
3390
- logger$q.warn("Failed to remove highlight from matching tab:", err);
3398
+ logger$r.warn("Failed to remove highlight from matching tab:", err);
3391
3399
  }
3392
3400
  }
3393
3401
  this.highlightCaptureCallback?.({
@@ -3418,12 +3426,12 @@ class TabManager {
3418
3426
  void 0,
3419
3427
  color
3420
3428
  ).catch(
3421
- (err) => logger$q.warn("Failed to update highlight color:", err)
3429
+ (err) => logger$r.warn("Failed to update highlight color:", err)
3422
3430
  );
3423
3431
  });
3424
3432
  }
3425
3433
  } catch (err) {
3426
- logger$q.warn("Failed to iterate highlights for color change:", err);
3434
+ logger$r.warn("Failed to iterate highlights for color change:", err);
3427
3435
  }
3428
3436
  }
3429
3437
  this.highlightCaptureCallback?.({
@@ -3478,7 +3486,7 @@ class TabManager {
3478
3486
  });
3479
3487
  })()`
3480
3488
  ).catch(
3481
- (err) => logger$q.warn("Failed to remove highlight marks:", err)
3489
+ (err) => logger$r.warn("Failed to remove highlight marks:", err)
3482
3490
  );
3483
3491
  }
3484
3492
  broadcastState(meta = { persistSession: false }) {
@@ -4682,7 +4690,7 @@ function errorResult(error, value) {
4682
4690
  function getErrorMessage(error, fallback = "Unknown error") {
4683
4691
  return error instanceof Error && error.message ? error.message : fallback;
4684
4692
  }
4685
- const logger$p = createLogger("Premium");
4693
+ const logger$q = createLogger("Premium");
4686
4694
  const VERIFICATION_API = process.env.VESSEL_PREMIUM_API || "https://vesselpremium.quantaintellect.com";
4687
4695
  const FREE_TOOL_ITERATION_LIMIT = 50;
4688
4696
  const REVALIDATION_INTERVAL_MS = 24 * 60 * 60 * 1e3;
@@ -4858,7 +4866,7 @@ async function verifySubscription$1(identifier) {
4858
4866
  });
4859
4867
  if (!res.ok) {
4860
4868
  const detail = await readApiErrorDetail(res);
4861
- logger$p.warn(
4869
+ logger$q.warn(
4862
4870
  "Verification API returned a non-OK status:",
4863
4871
  res.status,
4864
4872
  detail
@@ -4877,7 +4885,7 @@ async function verifySubscription$1(identifier) {
4877
4885
  setSetting("premium", updated);
4878
4886
  return updated;
4879
4887
  } catch (err) {
4880
- logger$p.warn("Verification failed:", err);
4888
+ logger$q.warn("Verification failed:", err);
4881
4889
  return current;
4882
4890
  }
4883
4891
  }
@@ -5532,7 +5540,7 @@ const EXTRACT_TIMEOUT_MAX_MS = 2e4;
5532
5540
  const MUTATION_CAPTURE_INTERVAL_MS = 5e3;
5533
5541
  const MUTATION_SETTLE_AFTER_MS = 1500;
5534
5542
  const AGENT_STREAM_IDLE_TIMEOUT_MS = 3e4;
5535
- const logger$o = createLogger("Extractor");
5543
+ const logger$p = createLogger("Extractor");
5536
5544
  const EXTRACTION_CACHE_TTL_MS = 1500;
5537
5545
  const MAX_EXTRACTION_CACHE_ENTRIES = 50;
5538
5546
  const extractionCache = new BoundedCache(
@@ -6297,9 +6305,9 @@ async function executeScript(webContents, script, options = {}) {
6297
6305
  const message = err instanceof Error ? err.message : String(err);
6298
6306
  const detail = `Failed to execute page script${label} on ${url}: ${message}`;
6299
6307
  if (options.warnOnFailure) {
6300
- logger$o.warn(detail);
6308
+ logger$p.warn(detail);
6301
6309
  } else {
6302
- logger$o.debug(detail);
6310
+ logger$p.debug(detail);
6303
6311
  }
6304
6312
  return null;
6305
6313
  } finally {
@@ -6408,7 +6416,7 @@ async function estimateExtractionTimeout(webContents) {
6408
6416
  return EXTRACT_TIMEOUT_BASE_MS + extra;
6409
6417
  }
6410
6418
  } catch (err) {
6411
- logger$o.warn("Failed to estimate extraction timeout, using base timeout:", err);
6419
+ logger$p.warn("Failed to estimate extraction timeout, using base timeout:", err);
6412
6420
  }
6413
6421
  return EXTRACT_TIMEOUT_BASE_MS;
6414
6422
  }
@@ -8239,7 +8247,7 @@ function recoverNarratedActionToolCalls(text, availableToolNames) {
8239
8247
  }
8240
8248
  return recovered;
8241
8249
  }
8242
- const logger$n = createLogger("OpenAIProvider");
8250
+ const logger$o = createLogger("OpenAIProvider");
8243
8251
  function shouldDebugAgentLoop() {
8244
8252
  const value = process.env.VESSEL_DEBUG_AGENT_LOOP;
8245
8253
  return value === "1" || value === "true";
@@ -8507,9 +8515,9 @@ function shouldRetryCompactToolLoop(profile, text, hasToolHistory, userMessage)
8507
8515
  function logAgentLoopDebug(payload) {
8508
8516
  if (!shouldDebugAgentLoop()) return;
8509
8517
  try {
8510
- logger$n.info(`[agent-debug] ${JSON.stringify(payload)}`);
8518
+ logger$o.info(`[agent-debug] ${JSON.stringify(payload)}`);
8511
8519
  } catch (err) {
8512
- logger$n.warn("Failed to serialize debug payload:", err);
8520
+ logger$o.warn("Failed to serialize debug payload:", err);
8513
8521
  }
8514
8522
  }
8515
8523
  function formatOpenAICompatErrorMessage(providerId, message) {
@@ -9113,7 +9121,7 @@ function createLocalPkceOAuthFlow(config) {
9113
9121
  isInProgress: () => activeFlow !== null
9114
9122
  };
9115
9123
  }
9116
- const logger$m = createLogger("CodexOAuth");
9124
+ const logger$n = createLogger("CodexOAuth");
9117
9125
  const ISSUER = "https://auth.openai.com";
9118
9126
  const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
9119
9127
  const SCOPE = "openid profile email offline_access api.connectors.read api.connectors.invoke";
@@ -9244,7 +9252,7 @@ function escapeHtml$1(text) {
9244
9252
  }
9245
9253
  const codexOAuth = createLocalPkceOAuthFlow({
9246
9254
  name: "Codex",
9247
- logger: logger$m,
9255
+ logger: logger$n,
9248
9256
  preferredPorts: [PREFERRED_PORT$1, FALLBACK_PORT$1],
9249
9257
  timeoutMs: AUTH_TIMEOUT_MS$1,
9250
9258
  callbackPath: () => "/auth/callback",
@@ -9268,7 +9276,7 @@ async function startCodexOAuth(onStatus) {
9268
9276
  function cancelCodexOAuth() {
9269
9277
  codexOAuth.cancel();
9270
9278
  }
9271
- const logger$l = createLogger("CodexProvider");
9279
+ const logger$m = createLogger("CodexProvider");
9272
9280
  const REFRESH_WINDOW_MS = 5 * 60 * 1e3;
9273
9281
  const CODEX_BACKEND_BASE_URL = "https://chatgpt.com/backend-api/codex";
9274
9282
  const CODEX_CLIENT_VERSION = "0.129.0";
@@ -9333,7 +9341,7 @@ class CodexProvider {
9333
9341
  async ensureFreshTokens() {
9334
9342
  if (Date.now() < this.tokens.expiresAt - REFRESH_WINDOW_MS) return;
9335
9343
  try {
9336
- logger$l.info("Refreshing Codex access token");
9344
+ logger$m.info("Refreshing Codex access token");
9337
9345
  const fresh = await refreshAccessToken(this.tokens);
9338
9346
  this.tokens = fresh;
9339
9347
  writeStoredCodexTokens(fresh);
@@ -9481,7 +9489,7 @@ class CodexProvider {
9481
9489
  } catch (err) {
9482
9490
  if (err.name !== "AbortError") {
9483
9491
  const msg = err instanceof Error ? err.message : String(err);
9484
- logger$l.error("Codex streamQuery error:", err);
9492
+ logger$m.error("Codex streamQuery error:", err);
9485
9493
  onChunk(`
9486
9494
 
9487
9495
  [Error: ${msg}]`);
@@ -9549,7 +9557,7 @@ class CodexProvider {
9549
9557
  } catch (err) {
9550
9558
  if (err.name !== "AbortError") {
9551
9559
  const msg = err instanceof Error ? err.message : String(err);
9552
- logger$l.error("Codex streamAgentQuery error:", err);
9560
+ logger$m.error("Codex streamAgentQuery error:", err);
9553
9561
  onChunk(`
9554
9562
 
9555
9563
  [Error: ${msg}]`);
@@ -10783,6 +10791,7 @@ function normalizeBookmarkMetadataUpdate(input) {
10783
10791
  }
10784
10792
  return normalized;
10785
10793
  }
10794
+ const logger$l = createLogger("BookmarkManager");
10786
10795
  const UNSORTED_ID = "unsorted";
10787
10796
  const ARCHIVE_FOLDER_NAME = "Archive";
10788
10797
  const NETSCAPE_BOOKMARKS_DOCTYPE = "<!DOCTYPE NETSCAPE-Bookmark-file-1>";
@@ -11354,7 +11363,8 @@ function importBookmarksFromJson(content) {
11354
11363
  save$1();
11355
11364
  emit$2();
11356
11365
  }
11357
- } catch {
11366
+ } catch (err) {
11367
+ logger$l.warn("Failed to import bookmarks from JSON:", err);
11358
11368
  errors++;
11359
11369
  }
11360
11370
  return { imported, skipped, errors };
@@ -15597,6 +15607,19 @@ Click one of these dialog actions. Do NOT click any other element.` : "";
15597
15607
  return `
15598
15608
  ${overlayHint}${actionsSuffix}${cartSummary}`;
15599
15609
  }
15610
+ async function followHrefFromClickResult(wc, beforeUrl, result, logMessage) {
15611
+ const hrefMatch = typeof result === "string" ? result.match(/\nhref: (https?:\/\/\S+)/) : null;
15612
+ if (!hrefMatch) return null;
15613
+ try {
15614
+ await loadPermittedUrl(wc, hrefMatch[1]);
15615
+ await waitForLoad(wc, 8e3);
15616
+ const hrefUrl = wc.getURL();
15617
+ if (hrefUrl !== beforeUrl) return `${result.split("\n")[0]} -> ${hrefUrl}`;
15618
+ } catch (err) {
15619
+ logger$j.warn(logMessage, err);
15620
+ }
15621
+ return null;
15622
+ }
15600
15623
  async function clickResolvedSelector(wc, selector) {
15601
15624
  if (selector.startsWith("__vessel_idx:")) {
15602
15625
  const idx = Number(selector.slice("__vessel_idx:".length));
@@ -15639,16 +15662,13 @@ Go back and select a different product.`;
15639
15662
  return `${result}${await buildCartSuccessSuffix(wc, beforeUrl2, idxOverlay)}`;
15640
15663
  }
15641
15664
  if (!idxOverlay) {
15642
- const hrefMatch = typeof result === "string" ? result.match(/\nhref: (https?:\/\/\S+)/) : null;
15643
- if (hrefMatch) {
15644
- try {
15645
- await loadPermittedUrl(wc, hrefMatch[1]);
15646
- await waitForLoad(wc, 8e3);
15647
- const hrefUrl = wc.getURL();
15648
- if (hrefUrl !== beforeUrl2) return `${result.split("\n")[0]} -> ${hrefUrl}`;
15649
- } catch {
15650
- }
15651
- }
15665
+ const hrefFallback = await followHrefFromClickResult(
15666
+ wc,
15667
+ beforeUrl2,
15668
+ result,
15669
+ "Failed to follow href fallback after click:"
15670
+ );
15671
+ if (hrefFallback) return hrefFallback;
15652
15672
  }
15653
15673
  return idxOverlay ? `${result}
15654
15674
  ${idxOverlay}` : `${result}
@@ -15706,16 +15726,13 @@ Go back and select a different product.`;
15706
15726
  return `${result}${await buildCartSuccessSuffix(wc, beforeUrl2, shadowOverlay)}`;
15707
15727
  }
15708
15728
  if (!shadowOverlay) {
15709
- const hrefMatch = typeof result === "string" ? result.match(/\nhref: (https?:\/\/\S+)/) : null;
15710
- if (hrefMatch) {
15711
- try {
15712
- await loadPermittedUrl(wc, hrefMatch[1]);
15713
- await waitForLoad(wc, 8e3);
15714
- const hrefUrl = wc.getURL();
15715
- if (hrefUrl !== beforeUrl2) return `${result.split("\n")[0]} -> ${hrefUrl}`;
15716
- } catch {
15717
- }
15718
- }
15729
+ const hrefFallback = await followHrefFromClickResult(
15730
+ wc,
15731
+ beforeUrl2,
15732
+ result,
15733
+ "Failed to follow href fallback after shadow click:"
15734
+ );
15735
+ if (hrefFallback) return hrefFallback;
15719
15736
  }
15720
15737
  return shadowOverlay ? `${result}
15721
15738
  ${shadowOverlay}` : `${result}
@@ -27300,7 +27317,8 @@ function getInstalledKits() {
27300
27317
  let files;
27301
27318
  try {
27302
27319
  files = fs$1.readdirSync(dir).filter((f) => f.endsWith(".kit.json"));
27303
- } catch {
27320
+ } catch (err) {
27321
+ logger$9.warn("Failed to read kit directory:", err);
27304
27322
  return [];
27305
27323
  }
27306
27324
  const kits = [];
@@ -27331,13 +27349,15 @@ async function installKitFromFile() {
27331
27349
  let raw;
27332
27350
  try {
27333
27351
  raw = fs$1.readFileSync(filePaths[0], "utf-8");
27334
- } catch {
27352
+ } catch (err) {
27353
+ logger$9.warn("Failed to read selected kit file:", err);
27335
27354
  return errorResult("Could not read the selected file.");
27336
27355
  }
27337
27356
  let parsed;
27338
27357
  try {
27339
27358
  parsed = JSON.parse(raw);
27340
- } catch {
27359
+ } catch (err) {
27360
+ logger$9.warn("Selected kit file is not valid JSON:", err);
27341
27361
  return errorResult("File is not valid JSON.");
27342
27362
  }
27343
27363
  if (!isValidKit(parsed)) {
@@ -27357,7 +27377,8 @@ async function installKitFromFile() {
27357
27377
  }
27358
27378
  try {
27359
27379
  fs$1.writeFileSync(dest, JSON.stringify(parsed, null, 2), "utf-8");
27360
- } catch {
27380
+ } catch (err) {
27381
+ logger$9.warn("Failed to save kit file:", err);
27361
27382
  return errorResult("Failed to save the kit file.");
27362
27383
  }
27363
27384
  return okResult({ kit: parsed });
@@ -27382,7 +27403,8 @@ function uninstallKit(id, scheduledKitIds) {
27382
27403
  try {
27383
27404
  fs$1.unlinkSync(target);
27384
27405
  return okResult();
27385
- } catch {
27406
+ } catch (err) {
27407
+ logger$9.warn("Failed to remove kit file:", err);
27386
27408
  return errorResult("Failed to remove the kit file.");
27387
27409
  }
27388
27410
  }