@quanta-intellect/vessel-browser 0.1.132 → 0.1.134
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
|
@@ -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$
|
|
117
|
+
const logger$x = 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$
|
|
142
|
+
logger$x.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$
|
|
151
|
+
logger$x.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$
|
|
170
|
+
logger$x.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$
|
|
188
|
+
logger$x.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$
|
|
206
|
+
logger$x.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$
|
|
224
|
+
logger$x.warn("Could not delete Codex token file:", err);
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
}
|
|
@@ -351,7 +351,9 @@ function persistNow() {
|
|
|
351
351
|
JSON.stringify(buildPersistedSettings(settings), null, 2),
|
|
352
352
|
{ encoding: "utf-8", mode: 384 }
|
|
353
353
|
)
|
|
354
|
-
).then(() => fs.promises.chmod(getSettingsPath(), 384).catch((
|
|
354
|
+
).then(() => fs.promises.chmod(getSettingsPath(), 384).catch((err) => {
|
|
355
|
+
logger$x.warn("Failed to chmod settings file:", err);
|
|
356
|
+
})).catch((err) => logger$x.error("Failed to save settings:", err));
|
|
355
357
|
}
|
|
356
358
|
function saveSettings() {
|
|
357
359
|
saveDirty = true;
|
|
@@ -530,7 +532,7 @@ const urlSafety = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
|
|
|
530
532
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
531
533
|
const MAX_CUSTOM_HISTORY = 50;
|
|
532
534
|
const READER_MODE_DATA_URL_PREFIX = "data:text/html;charset=utf-8,";
|
|
533
|
-
const logger$
|
|
535
|
+
const logger$w = createLogger("Tab");
|
|
534
536
|
const sessionCertExceptions = /* @__PURE__ */ new WeakMap();
|
|
535
537
|
const sessionsWithVerifyProc = /* @__PURE__ */ new WeakSet();
|
|
536
538
|
const CERT_VERIFY_TRUST = 0;
|
|
@@ -596,7 +598,7 @@ class Tab {
|
|
|
596
598
|
guardedLoadURL(url, options) {
|
|
597
599
|
const blockReason = this.getNavigationBlockReason(url);
|
|
598
600
|
if (blockReason) {
|
|
599
|
-
logger$
|
|
601
|
+
logger$w.warn(blockReason);
|
|
600
602
|
return blockReason;
|
|
601
603
|
}
|
|
602
604
|
void this.view.webContents.loadURL(url, options);
|
|
@@ -680,7 +682,7 @@ class Tab {
|
|
|
680
682
|
wc.setWindowOpenHandler(({ url, disposition }) => {
|
|
681
683
|
const error = this.getNavigationBlockReason(url);
|
|
682
684
|
if (error) {
|
|
683
|
-
logger$
|
|
685
|
+
logger$w.warn(error);
|
|
684
686
|
return { action: "deny" };
|
|
685
687
|
}
|
|
686
688
|
this.onOpenUrl?.({
|
|
@@ -694,7 +696,7 @@ class Tab {
|
|
|
694
696
|
const error = this.getNavigationBlockReason(url);
|
|
695
697
|
if (!error) return;
|
|
696
698
|
event.preventDefault();
|
|
697
|
-
logger$
|
|
699
|
+
logger$w.warn(`${context}: ${error}`);
|
|
698
700
|
};
|
|
699
701
|
wc.on("will-navigate", (event, url) => {
|
|
700
702
|
blockNavigation(event, url, "Blocked top-level navigation");
|
|
@@ -778,7 +780,7 @@ class Tab {
|
|
|
778
780
|
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 999px; }
|
|
779
781
|
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.22); }
|
|
780
782
|
::-webkit-scrollbar-corner { background: transparent; }
|
|
781
|
-
`).catch((err) => logger$
|
|
783
|
+
`).catch((err) => logger$w.warn("Failed to inject scrollbar CSS:", err));
|
|
782
784
|
});
|
|
783
785
|
wc.on("page-favicon-updated", (_, favicons) => {
|
|
784
786
|
this._state.favicon = favicons[0] || "";
|
|
@@ -814,7 +816,7 @@ class Tab {
|
|
|
814
816
|
).then((highlightedText) => {
|
|
815
817
|
this.buildContextMenu(wc, params, highlightedText.trim());
|
|
816
818
|
}).catch((err) => {
|
|
817
|
-
logger$
|
|
819
|
+
logger$w.warn("Failed to inspect highlighted text for context menu:", err);
|
|
818
820
|
this.buildContextMenu(wc, params, "");
|
|
819
821
|
});
|
|
820
822
|
});
|
|
@@ -1015,7 +1017,7 @@ class Tab {
|
|
|
1015
1017
|
"document.documentElement.outerHTML"
|
|
1016
1018
|
);
|
|
1017
1019
|
} catch (err) {
|
|
1018
|
-
logger$
|
|
1020
|
+
logger$w.warn("Failed to retrieve page source:", err);
|
|
1019
1021
|
return;
|
|
1020
1022
|
}
|
|
1021
1023
|
const escaped = html.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
@@ -1135,7 +1137,9 @@ class Tab {
|
|
|
1135
1137
|
range.insertNode(mark);
|
|
1136
1138
|
}
|
|
1137
1139
|
}
|
|
1138
|
-
} catch
|
|
1140
|
+
} catch {
|
|
1141
|
+
// Swallow — complex cross-node selections may fail to wrap
|
|
1142
|
+
}
|
|
1139
1143
|
sel.removeAllRanges();
|
|
1140
1144
|
// Notify main process for persistence
|
|
1141
1145
|
window.__vessel.notifyHighlightSelection(text);
|
|
@@ -1143,7 +1147,7 @@ class Tab {
|
|
|
1143
1147
|
document.addEventListener('mouseup', window.__vesselHighlightHandler);
|
|
1144
1148
|
}
|
|
1145
1149
|
})()
|
|
1146
|
-
`).catch((err) => logger$
|
|
1150
|
+
`).catch((err) => logger$w.warn("Failed to inject highlight listener:", err));
|
|
1147
1151
|
} else {
|
|
1148
1152
|
void wc.executeJavaScript(`
|
|
1149
1153
|
(function() {
|
|
@@ -1154,7 +1158,7 @@ class Tab {
|
|
|
1154
1158
|
delete window.__vesselHighlightHandler;
|
|
1155
1159
|
}
|
|
1156
1160
|
})()
|
|
1157
|
-
`).catch((err) => logger$
|
|
1161
|
+
`).catch((err) => logger$w.warn("Failed to remove highlight listener:", err));
|
|
1158
1162
|
}
|
|
1159
1163
|
}
|
|
1160
1164
|
get webContentsId() {
|
|
@@ -1191,7 +1195,7 @@ const SEARCH_ENGINE_PRESETS = {
|
|
|
1191
1195
|
ecosia: { label: "Ecosia", url: "https://www.ecosia.org/search?q=" },
|
|
1192
1196
|
kagi: { label: "Kagi", url: "https://kagi.com/search?q=" }
|
|
1193
1197
|
};
|
|
1194
|
-
const logger$
|
|
1198
|
+
const logger$v = createLogger("JsonPersistence");
|
|
1195
1199
|
function canUseSafeStorage() {
|
|
1196
1200
|
try {
|
|
1197
1201
|
return electron.safeStorage.isEncryptionAvailable();
|
|
@@ -1256,7 +1260,9 @@ function createDebouncedJsonPersistence({
|
|
|
1256
1260
|
data,
|
|
1257
1261
|
typeof data === "string" ? { encoding: "utf-8", mode: 384 } : { mode: 384 }
|
|
1258
1262
|
)
|
|
1259
|
-
).then(() => fs.promises.chmod(filePath2, 384).catch((
|
|
1263
|
+
).then(() => fs.promises.chmod(filePath2, 384).catch((err) => {
|
|
1264
|
+
logger$v.warn(`Failed to chmod ${logLabel}:`, err);
|
|
1265
|
+
})).catch((err) => logger$v.error(`Failed to save ${logLabel}:`, err));
|
|
1260
1266
|
};
|
|
1261
1267
|
const schedule = () => {
|
|
1262
1268
|
saveDirty2 = true;
|
|
@@ -1529,7 +1535,7 @@ function applyTextRangeMatch(match, solidColor, bgColor, fullText) {
|
|
|
1529
1535
|
try {
|
|
1530
1536
|
var mark = markTextSegment(segments[i], solidColor, bgColor, fullText);
|
|
1531
1537
|
if (mark) marks.unshift(mark);
|
|
1532
|
-
} catch (_e) {}
|
|
1538
|
+
} catch (_e) { /* text segment couldn't be marked — it may overlap other highlights */ }
|
|
1533
1539
|
}
|
|
1534
1540
|
return marks;
|
|
1535
1541
|
}
|
|
@@ -1869,7 +1875,7 @@ async function highlightBatchOnPage(wc, entries) {
|
|
|
1869
1875
|
el.style.setProperty('outline-color', c.solid, 'important');
|
|
1870
1876
|
el.style.setProperty('box-shadow', '0 0 8px ' + c.glow, 'important');
|
|
1871
1877
|
}
|
|
1872
|
-
} catch (_e) {}
|
|
1878
|
+
} catch (_e) { /* selector may not exist on current page */ }
|
|
1873
1879
|
}
|
|
1874
1880
|
}
|
|
1875
1881
|
})()
|
|
@@ -2948,7 +2954,7 @@ function destroySession(tabId) {
|
|
|
2948
2954
|
sessions.delete(tabId);
|
|
2949
2955
|
}
|
|
2950
2956
|
}
|
|
2951
|
-
const logger$
|
|
2957
|
+
const logger$u = createLogger("TabManager");
|
|
2952
2958
|
function sanitizeFilename(title, ext) {
|
|
2953
2959
|
const clean = title.replace(/[<>:"/\\|?*\x00-\x1f]/g, " ").replace(/\s+/g, " ").trim();
|
|
2954
2960
|
const escapedExt = ext.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -3367,7 +3373,7 @@ class TabManager {
|
|
|
3367
3373
|
}));
|
|
3368
3374
|
if (entries.length > 0) {
|
|
3369
3375
|
void highlightBatchOnPage(wc, entries).catch(
|
|
3370
|
-
(err) => logger$
|
|
3376
|
+
(err) => logger$u.warn("Failed to batch highlight:", err)
|
|
3371
3377
|
);
|
|
3372
3378
|
}
|
|
3373
3379
|
}
|
|
@@ -3389,12 +3395,12 @@ class TabManager {
|
|
|
3389
3395
|
const result = await captureSelectionHighlight(wc);
|
|
3390
3396
|
if (result.success && result.text) {
|
|
3391
3397
|
await highlightOnPage(wc, null, result.text, void 0, void 0, "yellow").catch(
|
|
3392
|
-
(err) => logger$
|
|
3398
|
+
(err) => logger$u.warn("Failed to capture highlight:", err)
|
|
3393
3399
|
);
|
|
3394
3400
|
}
|
|
3395
3401
|
this.highlightCaptureCallback?.(result);
|
|
3396
3402
|
} catch (err) {
|
|
3397
|
-
logger$
|
|
3403
|
+
logger$u.warn("Failed to capture highlight from page:", err);
|
|
3398
3404
|
this.highlightCaptureCallback?.({
|
|
3399
3405
|
success: false,
|
|
3400
3406
|
message: "Could not capture selection"
|
|
@@ -3419,7 +3425,7 @@ class TabManager {
|
|
|
3419
3425
|
void this.removeHighlightMarksForText(wc, text);
|
|
3420
3426
|
}
|
|
3421
3427
|
} catch (err) {
|
|
3422
|
-
logger$
|
|
3428
|
+
logger$u.warn("Failed to remove highlight from matching tab:", err);
|
|
3423
3429
|
}
|
|
3424
3430
|
}
|
|
3425
3431
|
this.highlightCaptureCallback?.({
|
|
@@ -3450,12 +3456,12 @@ class TabManager {
|
|
|
3450
3456
|
void 0,
|
|
3451
3457
|
color
|
|
3452
3458
|
).catch(
|
|
3453
|
-
(err) => logger$
|
|
3459
|
+
(err) => logger$u.warn("Failed to update highlight color:", err)
|
|
3454
3460
|
);
|
|
3455
3461
|
});
|
|
3456
3462
|
}
|
|
3457
3463
|
} catch (err) {
|
|
3458
|
-
logger$
|
|
3464
|
+
logger$u.warn("Failed to iterate highlights for color change:", err);
|
|
3459
3465
|
}
|
|
3460
3466
|
}
|
|
3461
3467
|
this.highlightCaptureCallback?.({
|
|
@@ -3510,7 +3516,7 @@ class TabManager {
|
|
|
3510
3516
|
});
|
|
3511
3517
|
})()`
|
|
3512
3518
|
).catch(
|
|
3513
|
-
(err) => logger$
|
|
3519
|
+
(err) => logger$u.warn("Failed to remove highlight marks:", err)
|
|
3514
3520
|
);
|
|
3515
3521
|
}
|
|
3516
3522
|
broadcastState(meta = { persistSession: false }) {
|
|
@@ -3532,9 +3538,6 @@ const AIChannels = {
|
|
|
3532
3538
|
AI_STREAM_END: "ai:stream-end",
|
|
3533
3539
|
AI_STREAM_IDLE: "ai:stream-idle",
|
|
3534
3540
|
AI_RESEARCH_CLARIFICATION: "ai:research-clarification",
|
|
3535
|
-
AUTOMATION_ACTIVITY_START: "automation:activity-start",
|
|
3536
|
-
AUTOMATION_ACTIVITY_CHUNK: "automation:activity-chunk",
|
|
3537
|
-
AUTOMATION_ACTIVITY_END: "automation:activity-end",
|
|
3538
3541
|
AI_CANCEL: "ai:cancel",
|
|
3539
3542
|
AI_FETCH_MODELS: "ai:fetch-models",
|
|
3540
3543
|
AGENT_RUNTIME_GET: "agent-runtime:get",
|
|
@@ -3561,6 +3564,9 @@ const AutomationChannels = {
|
|
|
3561
3564
|
AUTOMATION_GET_INSTALLED: "automation:get-installed",
|
|
3562
3565
|
AUTOMATION_INSTALL_FROM_FILE: "automation:install-from-file",
|
|
3563
3566
|
AUTOMATION_UNINSTALL: "automation:uninstall",
|
|
3567
|
+
AUTOMATION_ACTIVITY_START: "automation:activity-start",
|
|
3568
|
+
AUTOMATION_ACTIVITY_CHUNK: "automation:activity-chunk",
|
|
3569
|
+
AUTOMATION_ACTIVITY_END: "automation:activity-end",
|
|
3564
3570
|
SCHEDULE_GET_ALL: "schedule:get-all",
|
|
3565
3571
|
SCHEDULE_CREATE: "schedule:create",
|
|
3566
3572
|
SCHEDULE_UPDATE: "schedule:update",
|
|
@@ -3646,6 +3652,9 @@ const HumanVaultChannels = {
|
|
|
3646
3652
|
HUMAN_VAULT_REMOVE: "human-vault:remove",
|
|
3647
3653
|
HUMAN_VAULT_AUDIT_LOG: "human-vault:audit-log"
|
|
3648
3654
|
};
|
|
3655
|
+
const McpChannels = {
|
|
3656
|
+
MCP_REGENERATE_TOKEN: "mcp:regenerate-token"
|
|
3657
|
+
};
|
|
3649
3658
|
const OpenRouterChannels = {
|
|
3650
3659
|
OPENROUTER_START_AUTH: "openrouter:start-auth",
|
|
3651
3660
|
OPENROUTER_CANCEL_AUTH: "openrouter:cancel-auth",
|
|
@@ -3695,8 +3704,9 @@ const SettingsChannels = {
|
|
|
3695
3704
|
SETTINGS_SET: "settings:set",
|
|
3696
3705
|
SETTINGS_UPDATE: "settings:update",
|
|
3697
3706
|
SETTINGS_HEALTH_GET: "settings:health:get",
|
|
3698
|
-
SETTINGS_HEALTH_UPDATE: "settings:health:update"
|
|
3699
|
-
|
|
3707
|
+
SETTINGS_HEALTH_UPDATE: "settings:health:update"
|
|
3708
|
+
};
|
|
3709
|
+
const SupportChannels = {
|
|
3700
3710
|
SUPPORT_SUBMIT_FEEDBACK: "support:submit-feedback"
|
|
3701
3711
|
};
|
|
3702
3712
|
const TabChannels = {
|
|
@@ -3728,14 +3738,7 @@ const TabChannels = {
|
|
|
3728
3738
|
TAB_TOGGLE_MUTE: "tab:toggle-mute",
|
|
3729
3739
|
TAB_PRINT: "tab:print",
|
|
3730
3740
|
TAB_PRINT_TO_PDF: "tab:print-to-pdf",
|
|
3731
|
-
TAB_TOGGLE_PIP: "tab:toggle-pip"
|
|
3732
|
-
OPEN_NEW_WINDOW: "window:open-new",
|
|
3733
|
-
OPEN_PRIVATE_WINDOW: "private:open-window",
|
|
3734
|
-
IS_PRIVATE_MODE: "private:is-private",
|
|
3735
|
-
FIND_IN_PAGE_START: "find:start",
|
|
3736
|
-
FIND_IN_PAGE_NEXT: "find:next",
|
|
3737
|
-
FIND_IN_PAGE_STOP: "find:stop",
|
|
3738
|
-
FIND_IN_PAGE_RESULT: "find:result"
|
|
3741
|
+
TAB_TOGGLE_PIP: "tab:toggle-pip"
|
|
3739
3742
|
};
|
|
3740
3743
|
const UIChannels = {
|
|
3741
3744
|
SIDEBAR_TOGGLE: "ui:sidebar-toggle",
|
|
@@ -3764,7 +3767,14 @@ const VaultChannels = {
|
|
|
3764
3767
|
const WindowControlChannels = {
|
|
3765
3768
|
WINDOW_MINIMIZE: "window:minimize",
|
|
3766
3769
|
WINDOW_MAXIMIZE: "window:maximize",
|
|
3767
|
-
WINDOW_CLOSE: "window:close"
|
|
3770
|
+
WINDOW_CLOSE: "window:close",
|
|
3771
|
+
OPEN_NEW_WINDOW: "window:open-new",
|
|
3772
|
+
OPEN_PRIVATE_WINDOW: "private:open-window",
|
|
3773
|
+
IS_PRIVATE_MODE: "private:is-private",
|
|
3774
|
+
FIND_IN_PAGE_START: "find:start",
|
|
3775
|
+
FIND_IN_PAGE_NEXT: "find:next",
|
|
3776
|
+
FIND_IN_PAGE_STOP: "find:stop",
|
|
3777
|
+
FIND_IN_PAGE_RESULT: "find:result"
|
|
3768
3778
|
};
|
|
3769
3779
|
const Channels = {
|
|
3770
3780
|
...AIChannels,
|
|
@@ -3779,6 +3789,7 @@ const Channels = {
|
|
|
3779
3789
|
...HighlightChannels,
|
|
3780
3790
|
...HistoryChannels,
|
|
3781
3791
|
...HumanVaultChannels,
|
|
3792
|
+
...McpChannels,
|
|
3782
3793
|
...OpenRouterChannels,
|
|
3783
3794
|
...PermissionChannels,
|
|
3784
3795
|
...PremiumChannels,
|
|
@@ -3786,6 +3797,7 @@ const Channels = {
|
|
|
3786
3797
|
...SecurityChannels,
|
|
3787
3798
|
...SessionChannels,
|
|
3788
3799
|
...SettingsChannels,
|
|
3800
|
+
...SupportChannels,
|
|
3789
3801
|
...TabChannels,
|
|
3790
3802
|
...UIChannels,
|
|
3791
3803
|
...UpdateChannels,
|
|
@@ -4748,7 +4760,15 @@ function errorResult(error, value) {
|
|
|
4748
4760
|
function getErrorMessage(error, fallback = "Unknown error") {
|
|
4749
4761
|
return error instanceof Error && error.message ? error.message : fallback;
|
|
4750
4762
|
}
|
|
4751
|
-
|
|
4763
|
+
async function readJsonResponse(response, fallback, onError) {
|
|
4764
|
+
try {
|
|
4765
|
+
return await response.json();
|
|
4766
|
+
} catch (err) {
|
|
4767
|
+
onError(getErrorMessage(err, "JSON parse failed"));
|
|
4768
|
+
return fallback;
|
|
4769
|
+
}
|
|
4770
|
+
}
|
|
4771
|
+
const logger$t = createLogger("Premium");
|
|
4752
4772
|
const VERIFICATION_API = process.env.VESSEL_PREMIUM_API || "https://vesselpremium.quantaintellect.com";
|
|
4753
4773
|
const FREE_TOOL_ITERATION_LIMIT = 50;
|
|
4754
4774
|
const REVALIDATION_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -4924,7 +4944,7 @@ async function verifySubscription$1(identifier) {
|
|
|
4924
4944
|
});
|
|
4925
4945
|
if (!res.ok) {
|
|
4926
4946
|
const detail = await readApiErrorDetail(res);
|
|
4927
|
-
logger$
|
|
4947
|
+
logger$t.warn(
|
|
4928
4948
|
"Verification API returned a non-OK status:",
|
|
4929
4949
|
res.status,
|
|
4930
4950
|
detail
|
|
@@ -4943,7 +4963,7 @@ async function verifySubscription$1(identifier) {
|
|
|
4943
4963
|
setSetting("premium", updated);
|
|
4944
4964
|
return updated;
|
|
4945
4965
|
} catch (err) {
|
|
4946
|
-
logger$
|
|
4966
|
+
logger$t.warn("Verification failed:", err);
|
|
4947
4967
|
return current;
|
|
4948
4968
|
}
|
|
4949
4969
|
}
|
|
@@ -4961,7 +4981,11 @@ async function requestActivationCode(email) {
|
|
|
4961
4981
|
headers: { "Content-Type": "application/json" },
|
|
4962
4982
|
body: JSON.stringify({ email: normalizedEmail })
|
|
4963
4983
|
});
|
|
4964
|
-
const data = await
|
|
4984
|
+
const data = await readJsonResponse(
|
|
4985
|
+
res,
|
|
4986
|
+
{},
|
|
4987
|
+
(msg) => logger$t.warn("Failed to parse premium activation response:", msg)
|
|
4988
|
+
);
|
|
4965
4989
|
if (!res.ok || !data.challengeToken) {
|
|
4966
4990
|
return errorResult(data.error || `HTTP ${res.status}`);
|
|
4967
4991
|
}
|
|
@@ -5002,7 +5026,11 @@ async function verifyActivationCode(email, code, challengeToken) {
|
|
|
5002
5026
|
challengeToken: challengeToken.trim()
|
|
5003
5027
|
})
|
|
5004
5028
|
});
|
|
5005
|
-
const data = await
|
|
5029
|
+
const data = await readJsonResponse(
|
|
5030
|
+
res,
|
|
5031
|
+
{},
|
|
5032
|
+
(msg) => logger$t.warn("Failed to parse premium verification response:", msg)
|
|
5033
|
+
);
|
|
5006
5034
|
if (!res.ok) {
|
|
5007
5035
|
return errorResult(data.error || `HTTP ${res.status}`, {
|
|
5008
5036
|
state: getPremiumState()
|
|
@@ -5598,7 +5626,7 @@ const EXTRACT_TIMEOUT_MAX_MS = 2e4;
|
|
|
5598
5626
|
const MUTATION_CAPTURE_INTERVAL_MS = 5e3;
|
|
5599
5627
|
const MUTATION_SETTLE_AFTER_MS = 1500;
|
|
5600
5628
|
const AGENT_STREAM_IDLE_TIMEOUT_MS = 3e4;
|
|
5601
|
-
const logger$
|
|
5629
|
+
const logger$s = createLogger("Extractor");
|
|
5602
5630
|
const EXTRACTION_CACHE_TTL_MS = 1500;
|
|
5603
5631
|
const MAX_EXTRACTION_CACHE_ENTRIES = 50;
|
|
5604
5632
|
const extractionCache = new BoundedCache(
|
|
@@ -5645,6 +5673,7 @@ const PRELOAD_EXTRACTION_SCRIPT = String.raw`
|
|
|
5645
5673
|
}
|
|
5646
5674
|
}
|
|
5647
5675
|
} catch (_error) {
|
|
5676
|
+
// Structured extraction unavailable, fall through to direct extraction
|
|
5648
5677
|
}
|
|
5649
5678
|
return null;
|
|
5650
5679
|
})()
|
|
@@ -6284,9 +6313,9 @@ const DIRECT_EXTRACTION_SCRIPT = String.raw`
|
|
|
6284
6313
|
} else if (parsed && typeof parsed === "object") {
|
|
6285
6314
|
jsonLd.push(parsed);
|
|
6286
6315
|
}
|
|
6287
|
-
} catch (_e) {}
|
|
6316
|
+
} catch (_e) { /* skip malformed JSON-LD block */ }
|
|
6288
6317
|
});
|
|
6289
|
-
} catch (_e) {}
|
|
6318
|
+
} catch (_e) { /* no JSON-LD scripts found or querySelectorAll failed */ }
|
|
6290
6319
|
|
|
6291
6320
|
// Extract meta tags as fallback
|
|
6292
6321
|
var metaTags = {};
|
|
@@ -6299,8 +6328,7 @@ const DIRECT_EXTRACTION_SCRIPT = String.raw`
|
|
|
6299
6328
|
});
|
|
6300
6329
|
var canonical = document.querySelector('link[rel="canonical"]');
|
|
6301
6330
|
if (canonical && canonical.getAttribute("href")) metaTags["canonical"] = canonical.getAttribute("href");
|
|
6302
|
-
} catch (_e) {}
|
|
6303
|
-
|
|
6331
|
+
} catch (_e) { /* meta tag extraction failed — non-critical */ }
|
|
6304
6332
|
return {
|
|
6305
6333
|
title: document.title,
|
|
6306
6334
|
content: getCleanBodyText(),
|
|
@@ -6363,9 +6391,9 @@ async function executeScript(webContents, script, options = {}) {
|
|
|
6363
6391
|
const message = err instanceof Error ? err.message : String(err);
|
|
6364
6392
|
const detail = `Failed to execute page script${label} on ${url}: ${message}`;
|
|
6365
6393
|
if (options.warnOnFailure) {
|
|
6366
|
-
logger$
|
|
6394
|
+
logger$s.warn(detail);
|
|
6367
6395
|
} else {
|
|
6368
|
-
logger$
|
|
6396
|
+
logger$s.debug(detail);
|
|
6369
6397
|
}
|
|
6370
6398
|
return null;
|
|
6371
6399
|
} finally {
|
|
@@ -6474,7 +6502,7 @@ async function estimateExtractionTimeout(webContents) {
|
|
|
6474
6502
|
return EXTRACT_TIMEOUT_BASE_MS + extra;
|
|
6475
6503
|
}
|
|
6476
6504
|
} catch (err) {
|
|
6477
|
-
logger$
|
|
6505
|
+
logger$s.warn("Failed to estimate extraction timeout, using base timeout:", err);
|
|
6478
6506
|
}
|
|
6479
6507
|
return EXTRACT_TIMEOUT_BASE_MS;
|
|
6480
6508
|
}
|
|
@@ -7442,7 +7470,7 @@ function isClickReadLoop(names) {
|
|
|
7442
7470
|
return clickReadPairs >= 2;
|
|
7443
7471
|
}
|
|
7444
7472
|
const TERMINAL_TOOL_RESULT = "__VESSEL_TERMINAL_TOOL_RESULT__";
|
|
7445
|
-
const logger$
|
|
7473
|
+
const logger$r = createLogger("PromptCache");
|
|
7446
7474
|
function shortHash(value) {
|
|
7447
7475
|
return crypto$2.createHash("sha256").update(value).digest("hex").slice(0, 12);
|
|
7448
7476
|
}
|
|
@@ -7494,7 +7522,7 @@ function logOpenAIPromptCacheUsage(usage, context) {
|
|
|
7494
7522
|
const details = record.prompt_tokens_details;
|
|
7495
7523
|
const cachedTokens = details && typeof details === "object" ? numericField(details, "cached_tokens") : null;
|
|
7496
7524
|
if (promptTokens === null && cachedTokens === null) return;
|
|
7497
|
-
logger$
|
|
7525
|
+
logger$r.debug("OpenAI prompt cache usage", {
|
|
7498
7526
|
model: context.model,
|
|
7499
7527
|
mode: context.mode,
|
|
7500
7528
|
promptTokens,
|
|
@@ -7510,7 +7538,7 @@ function logAnthropicPromptCacheUsage(usage, context) {
|
|
|
7510
7538
|
if (inputTokens === null && cacheCreationTokens === null && cacheReadTokens === null) {
|
|
7511
7539
|
return;
|
|
7512
7540
|
}
|
|
7513
|
-
logger$
|
|
7541
|
+
logger$r.debug("Anthropic prompt cache usage", {
|
|
7514
7542
|
model: context.model,
|
|
7515
7543
|
mode: context.mode,
|
|
7516
7544
|
inputTokens,
|
|
@@ -8403,7 +8431,7 @@ function recoverNarratedActionToolCalls(text, availableToolNames) {
|
|
|
8403
8431
|
}
|
|
8404
8432
|
return recovered;
|
|
8405
8433
|
}
|
|
8406
|
-
const logger$
|
|
8434
|
+
const logger$q = createLogger("OpenAIProvider");
|
|
8407
8435
|
function shouldDebugAgentLoop() {
|
|
8408
8436
|
const value = process.env.VESSEL_DEBUG_AGENT_LOOP;
|
|
8409
8437
|
return value === "1" || value === "true";
|
|
@@ -8671,9 +8699,9 @@ function shouldRetryCompactToolLoop(profile, text, hasToolHistory, userMessage)
|
|
|
8671
8699
|
function logAgentLoopDebug(payload) {
|
|
8672
8700
|
if (!shouldDebugAgentLoop()) return;
|
|
8673
8701
|
try {
|
|
8674
|
-
logger$
|
|
8702
|
+
logger$q.info(`[agent-debug] ${JSON.stringify(payload)}`);
|
|
8675
8703
|
} catch (err) {
|
|
8676
|
-
logger$
|
|
8704
|
+
logger$q.warn("Failed to serialize debug payload:", err);
|
|
8677
8705
|
}
|
|
8678
8706
|
}
|
|
8679
8707
|
function formatOpenAICompatErrorMessage(providerId, message) {
|
|
@@ -9113,6 +9141,9 @@ class OpenAICompatProvider {
|
|
|
9113
9141
|
this.abortController?.abort();
|
|
9114
9142
|
}
|
|
9115
9143
|
}
|
|
9144
|
+
function escapeHtml(value) {
|
|
9145
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
9146
|
+
}
|
|
9116
9147
|
async function openExternalAllowlisted(url, rule) {
|
|
9117
9148
|
const parsed = new URL(url);
|
|
9118
9149
|
const schemes = rule.schemes ?? ["https:"];
|
|
@@ -9297,7 +9328,7 @@ function createLocalPkceOAuthFlow(config) {
|
|
|
9297
9328
|
isInProgress: () => activeFlow !== null
|
|
9298
9329
|
};
|
|
9299
9330
|
}
|
|
9300
|
-
const logger$
|
|
9331
|
+
const logger$p = createLogger("CodexOAuth");
|
|
9301
9332
|
const ISSUER = "https://auth.openai.com";
|
|
9302
9333
|
const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
9303
9334
|
const SCOPE = "openid profile email offline_access api.connectors.read api.connectors.invoke";
|
|
@@ -9423,12 +9454,9 @@ async function refreshAccessToken(tokens) {
|
|
|
9423
9454
|
};
|
|
9424
9455
|
return refreshedTokens;
|
|
9425
9456
|
}
|
|
9426
|
-
function escapeHtml$1(text) {
|
|
9427
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
9428
|
-
}
|
|
9429
9457
|
const codexOAuth = createLocalPkceOAuthFlow({
|
|
9430
9458
|
name: "Codex",
|
|
9431
|
-
logger: logger$
|
|
9459
|
+
logger: logger$p,
|
|
9432
9460
|
preferredPorts: [PREFERRED_PORT$1, FALLBACK_PORT$1],
|
|
9433
9461
|
timeoutMs: AUTH_TIMEOUT_MS$1,
|
|
9434
9462
|
callbackPath: () => "/auth/callback",
|
|
@@ -9437,7 +9465,7 @@ const codexOAuth = createLocalPkceOAuthFlow({
|
|
|
9437
9465
|
buildAuthorizeUrl: ({ callbackUrl, pkce, state: state2 }) => buildAuthorizeUrl(callbackUrl, pkce, state2),
|
|
9438
9466
|
exchangeCode: ({ code, callbackUrl, codeVerifier }) => exchangeCodeForTokens(code, callbackUrl, codeVerifier),
|
|
9439
9467
|
successHtml: (tokens) => {
|
|
9440
|
-
const label = escapeHtml
|
|
9468
|
+
const label = escapeHtml(tokens.accountEmail || tokens.accountId);
|
|
9441
9469
|
return `<!DOCTYPE html>
|
|
9442
9470
|
<html><head><meta charset="utf-8"><title>Vessel — Signed In</title>
|
|
9443
9471
|
<style>body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#111;color:#eee}</style></head>
|
|
@@ -9452,7 +9480,7 @@ async function startCodexOAuth(onStatus) {
|
|
|
9452
9480
|
function cancelCodexOAuth() {
|
|
9453
9481
|
codexOAuth.cancel();
|
|
9454
9482
|
}
|
|
9455
|
-
const logger$
|
|
9483
|
+
const logger$o = createLogger("CodexProvider");
|
|
9456
9484
|
const REFRESH_WINDOW_MS = 5 * 60 * 1e3;
|
|
9457
9485
|
const CODEX_BACKEND_BASE_URL = "https://chatgpt.com/backend-api/codex";
|
|
9458
9486
|
const CODEX_CLIENT_VERSION = "0.129.0";
|
|
@@ -9517,7 +9545,7 @@ class CodexProvider {
|
|
|
9517
9545
|
async ensureFreshTokens() {
|
|
9518
9546
|
if (Date.now() < this.tokens.expiresAt - REFRESH_WINDOW_MS) return;
|
|
9519
9547
|
try {
|
|
9520
|
-
logger$
|
|
9548
|
+
logger$o.info("Refreshing Codex access token");
|
|
9521
9549
|
const fresh = await refreshAccessToken(this.tokens);
|
|
9522
9550
|
this.tokens = fresh;
|
|
9523
9551
|
writeStoredCodexTokens(fresh);
|
|
@@ -9665,7 +9693,7 @@ class CodexProvider {
|
|
|
9665
9693
|
} catch (err) {
|
|
9666
9694
|
if (err.name !== "AbortError") {
|
|
9667
9695
|
const msg = err instanceof Error ? err.message : String(err);
|
|
9668
|
-
logger$
|
|
9696
|
+
logger$o.error("Codex streamQuery error:", err);
|
|
9669
9697
|
onChunk(`
|
|
9670
9698
|
|
|
9671
9699
|
[Error: ${msg}]`);
|
|
@@ -9733,7 +9761,7 @@ class CodexProvider {
|
|
|
9733
9761
|
} catch (err) {
|
|
9734
9762
|
if (err.name !== "AbortError") {
|
|
9735
9763
|
const msg = err instanceof Error ? err.message : String(err);
|
|
9736
|
-
logger$
|
|
9764
|
+
logger$o.error("Codex streamAgentQuery error:", err);
|
|
9737
9765
|
onChunk(`
|
|
9738
9766
|
|
|
9739
9767
|
[Error: ${msg}]`);
|
|
@@ -10967,7 +10995,7 @@ function normalizeBookmarkMetadataUpdate(input) {
|
|
|
10967
10995
|
}
|
|
10968
10996
|
return normalized;
|
|
10969
10997
|
}
|
|
10970
|
-
const logger$
|
|
10998
|
+
const logger$n = createLogger("BookmarkManager");
|
|
10971
10999
|
const UNSORTED_ID = "unsorted";
|
|
10972
11000
|
const ARCHIVE_FOLDER_NAME = "Archive";
|
|
10973
11001
|
const NETSCAPE_BOOKMARKS_DOCTYPE = "<!DOCTYPE NETSCAPE-Bookmark-file-1>";
|
|
@@ -11540,7 +11568,7 @@ function importBookmarksFromJson(content) {
|
|
|
11540
11568
|
emit$2();
|
|
11541
11569
|
}
|
|
11542
11570
|
} catch (err) {
|
|
11543
|
-
logger$
|
|
11571
|
+
logger$n.warn("Failed to import bookmarks from JSON:", err);
|
|
11544
11572
|
errors++;
|
|
11545
11573
|
}
|
|
11546
11574
|
return { imported, skipped, errors };
|
|
@@ -11945,6 +11973,7 @@ async function resolveSelector(wc, index, selector) {
|
|
|
11945
11973
|
if (extractedSelector) return extractedSelector;
|
|
11946
11974
|
return null;
|
|
11947
11975
|
}
|
|
11976
|
+
const logger$m = createLogger("LinkValidation");
|
|
11948
11977
|
const DEAD_STATUS_CODES = /* @__PURE__ */ new Set([404, 410, 451]);
|
|
11949
11978
|
const HEAD_FALLBACK_STATUS_CODES = /* @__PURE__ */ new Set([400, 403, 404, 405, 406, 500, 501]);
|
|
11950
11979
|
function isHttpUrl(value) {
|
|
@@ -11967,7 +11996,9 @@ async function requestUrl(url, method, timeoutMs) {
|
|
|
11967
11996
|
"user-agent": "Vessel/0.1.0 (+https://github.com/unmodeled-tyler/vessel-browser)"
|
|
11968
11997
|
}
|
|
11969
11998
|
});
|
|
11970
|
-
await response.body?.cancel().catch(() =>
|
|
11999
|
+
await response.body?.cancel().catch((err) => {
|
|
12000
|
+
logger$m.debug("Failed to cancel response body:", err);
|
|
12001
|
+
});
|
|
11971
12002
|
return response;
|
|
11972
12003
|
} finally {
|
|
11973
12004
|
clearTimeout(timer);
|
|
@@ -12030,7 +12061,7 @@ function formatDeadLinkMessage(label, result) {
|
|
|
12030
12061
|
const status = result.statusCode ? `HTTP ${result.statusCode}` : "dead link";
|
|
12031
12062
|
return `Skipped stale link "${label}" because ${destination} returned ${status}. Try a different link or URL instead.`;
|
|
12032
12063
|
}
|
|
12033
|
-
const logger$
|
|
12064
|
+
const logger$l = createLogger("Screenshot");
|
|
12034
12065
|
const SCREENSHOT_RETRY_COUNT = 3;
|
|
12035
12066
|
const SCREENSHOT_RETRY_BASE_DELAY_MS = 120;
|
|
12036
12067
|
async function captureScreenshot(wc) {
|
|
@@ -12052,7 +12083,7 @@ async function captureScreenshot(wc) {
|
|
|
12052
12083
|
}
|
|
12053
12084
|
}
|
|
12054
12085
|
} catch (err) {
|
|
12055
|
-
logger$
|
|
12086
|
+
logger$l.debug(
|
|
12056
12087
|
`capturePage attempt ${attempt + 1} failed; retrying if attempts remain.`,
|
|
12057
12088
|
getErrorMessage(err)
|
|
12058
12089
|
);
|
|
@@ -14529,7 +14560,7 @@ class TabMutex {
|
|
|
14529
14560
|
return run;
|
|
14530
14561
|
}
|
|
14531
14562
|
}
|
|
14532
|
-
const logger$
|
|
14563
|
+
const logger$k = createLogger("PageActions");
|
|
14533
14564
|
const DEFAULT_PAGE_SCRIPT_TIMEOUT_MS = 1500;
|
|
14534
14565
|
const PAGE_SCRIPT_TIMEOUT = /* @__PURE__ */ Symbol("page-script-timeout");
|
|
14535
14566
|
function pageBusyError(action) {
|
|
@@ -14557,7 +14588,7 @@ async function executePageScript(wc, script, options) {
|
|
|
14557
14588
|
return result;
|
|
14558
14589
|
} catch (err) {
|
|
14559
14590
|
const label = options?.label ? ` (${options.label})` : "";
|
|
14560
|
-
logger$
|
|
14591
|
+
logger$k.warn(`Failed to execute page script${label}:`, err);
|
|
14561
14592
|
return null;
|
|
14562
14593
|
} finally {
|
|
14563
14594
|
if (timer) {
|
|
@@ -14754,7 +14785,9 @@ Page title: ${title}` : "";
|
|
|
14754
14785
|
signals.push('consent-banner:' + consentSelectors[i]);
|
|
14755
14786
|
break;
|
|
14756
14787
|
}
|
|
14757
|
-
} catch
|
|
14788
|
+
} catch {
|
|
14789
|
+
// Swallow — cross-origin frames may block selector access
|
|
14790
|
+
}
|
|
14758
14791
|
}
|
|
14759
14792
|
var vw = window.innerWidth || 0;
|
|
14760
14793
|
var vh = window.innerHeight || 0;
|
|
@@ -14797,7 +14830,7 @@ Search results snapshot:
|
|
|
14797
14830
|
${truncated}`;
|
|
14798
14831
|
}
|
|
14799
14832
|
} catch (err) {
|
|
14800
|
-
logger$
|
|
14833
|
+
logger$k.warn("Failed to build post-search summary, falling back to nav summary:", err);
|
|
14801
14834
|
}
|
|
14802
14835
|
const fallback = await getPostNavSummary(wc);
|
|
14803
14836
|
return fallback ? `${fallback}
|
|
@@ -14820,7 +14853,7 @@ Page snapshot after navigation:
|
|
|
14820
14853
|
${truncated}`;
|
|
14821
14854
|
}
|
|
14822
14855
|
} catch (err) {
|
|
14823
|
-
logger$
|
|
14856
|
+
logger$k.warn("Failed to build post-click navigation summary:", err);
|
|
14824
14857
|
}
|
|
14825
14858
|
return "";
|
|
14826
14859
|
}
|
|
@@ -15710,7 +15743,7 @@ async function restoreLocaleSnapshot(wc, snapshot2) {
|
|
|
15710
15743
|
}
|
|
15711
15744
|
}
|
|
15712
15745
|
} catch (err) {
|
|
15713
|
-
logger$
|
|
15746
|
+
logger$k.warn("Failed to restore locale via history navigation, trying URL reload fallback:", err);
|
|
15714
15747
|
}
|
|
15715
15748
|
if (snapshot2.url && snapshot2.url !== wc.getURL()) {
|
|
15716
15749
|
try {
|
|
@@ -15719,7 +15752,7 @@ async function restoreLocaleSnapshot(wc, snapshot2) {
|
|
|
15719
15752
|
await waitForLoad(wc, 3e3);
|
|
15720
15753
|
return;
|
|
15721
15754
|
} catch (err) {
|
|
15722
|
-
logger$
|
|
15755
|
+
logger$k.warn("Failed to restore locale via safe URL load, trying page reload fallback:", err);
|
|
15723
15756
|
}
|
|
15724
15757
|
}
|
|
15725
15758
|
if (snapshot2.url) {
|
|
@@ -15727,7 +15760,7 @@ async function restoreLocaleSnapshot(wc, snapshot2) {
|
|
|
15727
15760
|
await wc.reload();
|
|
15728
15761
|
await waitForLoad(wc, 3e3);
|
|
15729
15762
|
} catch (err) {
|
|
15730
|
-
logger$
|
|
15763
|
+
logger$k.warn("Failed to restore locale via page reload:", err);
|
|
15731
15764
|
}
|
|
15732
15765
|
}
|
|
15733
15766
|
}
|
|
@@ -15792,7 +15825,7 @@ async function followHrefFromClickResult(wc, beforeUrl, result, logMessage) {
|
|
|
15792
15825
|
const hrefUrl = wc.getURL();
|
|
15793
15826
|
if (hrefUrl !== beforeUrl) return `${result.split("\n")[0]} -> ${hrefUrl}`;
|
|
15794
15827
|
} catch (err) {
|
|
15795
|
-
logger$
|
|
15828
|
+
logger$k.warn(logMessage, err);
|
|
15796
15829
|
}
|
|
15797
15830
|
return null;
|
|
15798
15831
|
}
|
|
@@ -16004,7 +16037,7 @@ ${postActivationOverlayHint}`;
|
|
|
16004
16037
|
return `${clickText} -> ${hrefFallbackUrl} (recovered via href fallback)`;
|
|
16005
16038
|
}
|
|
16006
16039
|
} catch (err) {
|
|
16007
|
-
logger$
|
|
16040
|
+
logger$k.warn("Failed href fallback after click, returning generic click result:", err);
|
|
16008
16041
|
}
|
|
16009
16042
|
}
|
|
16010
16043
|
}
|
|
@@ -16049,7 +16082,7 @@ async function tryAutoDismissCartDialog(wc) {
|
|
|
16049
16082
|
return result;
|
|
16050
16083
|
}
|
|
16051
16084
|
} catch (err) {
|
|
16052
|
-
logger$
|
|
16085
|
+
logger$k.warn("Failed to auto-dismiss cart dialog, falling back to dialog actions:", err);
|
|
16053
16086
|
}
|
|
16054
16087
|
return null;
|
|
16055
16088
|
}
|
|
@@ -16502,7 +16535,9 @@ async function tryDismissConsentIframe(wc) {
|
|
|
16502
16535
|
return 'Clicked iframe consent button: ' + text.slice(0, 60);
|
|
16503
16536
|
}
|
|
16504
16537
|
}
|
|
16505
|
-
} catch
|
|
16538
|
+
} catch {
|
|
16539
|
+
// Swallow — selector may be invalid or cross-origin frame may block access
|
|
16540
|
+
}
|
|
16506
16541
|
}
|
|
16507
16542
|
// Text-match fallback on all buttons
|
|
16508
16543
|
var buttons = document.querySelectorAll('button, [role="button"], a.message-component');
|
|
@@ -17809,60 +17844,7 @@ WARNING: This page shows no results. You likely clicked a filter or category lin
|
|
|
17809
17844
|
}
|
|
17810
17845
|
return "";
|
|
17811
17846
|
}
|
|
17812
|
-
const KNOWN_TOOLS =
|
|
17813
|
-
"current_tab",
|
|
17814
|
-
"list_tabs",
|
|
17815
|
-
"switch_tab",
|
|
17816
|
-
"create_tab",
|
|
17817
|
-
"navigate",
|
|
17818
|
-
"go_back",
|
|
17819
|
-
"go_forward",
|
|
17820
|
-
"reload",
|
|
17821
|
-
"click",
|
|
17822
|
-
"inspect_element",
|
|
17823
|
-
"type_text",
|
|
17824
|
-
"select_option",
|
|
17825
|
-
"submit_form",
|
|
17826
|
-
"press_key",
|
|
17827
|
-
"scroll",
|
|
17828
|
-
"hover",
|
|
17829
|
-
"focus",
|
|
17830
|
-
"set_ad_blocking",
|
|
17831
|
-
"dismiss_popup",
|
|
17832
|
-
"clear_overlays",
|
|
17833
|
-
"read_page",
|
|
17834
|
-
"screenshot",
|
|
17835
|
-
"wait_for",
|
|
17836
|
-
"create_checkpoint",
|
|
17837
|
-
"restore_checkpoint",
|
|
17838
|
-
"save_session",
|
|
17839
|
-
"load_session",
|
|
17840
|
-
"list_sessions",
|
|
17841
|
-
"delete_session",
|
|
17842
|
-
"list_bookmarks",
|
|
17843
|
-
"search_bookmarks",
|
|
17844
|
-
"create_bookmark_folder",
|
|
17845
|
-
"save_bookmark",
|
|
17846
|
-
"organize_bookmark",
|
|
17847
|
-
"archive_bookmark",
|
|
17848
|
-
"open_bookmark",
|
|
17849
|
-
"highlight",
|
|
17850
|
-
"clear_highlights",
|
|
17851
|
-
"flow_start",
|
|
17852
|
-
"flow_advance",
|
|
17853
|
-
"flow_status",
|
|
17854
|
-
"flow_end",
|
|
17855
|
-
"suggest",
|
|
17856
|
-
"fill_form",
|
|
17857
|
-
"login",
|
|
17858
|
-
"search",
|
|
17859
|
-
"paginate",
|
|
17860
|
-
"accept_cookies",
|
|
17861
|
-
"extract_table",
|
|
17862
|
-
"scroll_to_element",
|
|
17863
|
-
"metrics",
|
|
17864
|
-
"wait_for_navigation"
|
|
17865
|
-
]);
|
|
17847
|
+
const KNOWN_TOOLS = new Set(TOOL_DEFINITIONS.map((d) => d.name));
|
|
17866
17848
|
async function executeAction(name, args, ctx) {
|
|
17867
17849
|
name = normalizeToolAlias(name);
|
|
17868
17850
|
if (ctx.tabId && ctx._tabMutex) {
|
|
@@ -18204,7 +18186,7 @@ async function executeAction(name, args, ctx) {
|
|
|
18204
18186
|
)
|
|
18205
18187
|
]);
|
|
18206
18188
|
} catch (err) {
|
|
18207
|
-
logger$
|
|
18189
|
+
logger$k.warn("Failed to extract content for read_page, falling back to lighter recovery:", err);
|
|
18208
18190
|
content = null;
|
|
18209
18191
|
}
|
|
18210
18192
|
if (!content || content.content.length === 0) {
|
|
@@ -18221,12 +18203,12 @@ async function executeAction(name, args, ctx) {
|
|
|
18221
18203
|
new Promise((resolve) => setTimeout(() => resolve(null), 3e3))
|
|
18222
18204
|
]);
|
|
18223
18205
|
} catch (err) {
|
|
18224
|
-
logger$
|
|
18206
|
+
logger$k.warn("Failed to re-extract content after iframe consent dismissal:", err);
|
|
18225
18207
|
content = null;
|
|
18226
18208
|
}
|
|
18227
18209
|
}
|
|
18228
18210
|
} catch (err) {
|
|
18229
|
-
logger$
|
|
18211
|
+
logger$k.warn("Failed iframe consent dismissal during read_page recovery:", err);
|
|
18230
18212
|
}
|
|
18231
18213
|
}
|
|
18232
18214
|
if (content && content.content.length > 0) {
|
|
@@ -18639,7 +18621,7 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
18639
18621
|
try {
|
|
18640
18622
|
page = await extractContent(wc);
|
|
18641
18623
|
} catch (err) {
|
|
18642
|
-
logger$
|
|
18624
|
+
logger$k.warn("Failed to extract content for suggest:", err);
|
|
18643
18625
|
return "Could not read page. Try navigate to a working URL.";
|
|
18644
18626
|
}
|
|
18645
18627
|
const suggestions = [];
|
|
@@ -19027,7 +19009,7 @@ WARNING: You have clicked ${clickStreakCount} elements on this page without veri
|
|
|
19027
19009
|
}
|
|
19028
19010
|
return formattedResult + await getPostActionState$1(ctx, name) + clickNavSummary + streakWarning + flowCtx;
|
|
19029
19011
|
}
|
|
19030
|
-
const logger$
|
|
19012
|
+
const logger$j = createLogger("ResearchOrchestrator");
|
|
19031
19013
|
const MAX_THREADS = 5;
|
|
19032
19014
|
const MAX_TRACE_ARGS_CHARS = 1200;
|
|
19033
19015
|
const MAX_TRACE_RESULT_CHARS = 2e3;
|
|
@@ -19216,7 +19198,7 @@ class ResearchOrchestrator {
|
|
|
19216
19198
|
}
|
|
19217
19199
|
stopAndSynthesizeCurrentFindings() {
|
|
19218
19200
|
if (this.state.phase !== "executing") {
|
|
19219
|
-
logger$
|
|
19201
|
+
logger$j.warn("Not executing, ignoring stopAndSynthesizeCurrentFindings");
|
|
19220
19202
|
return;
|
|
19221
19203
|
}
|
|
19222
19204
|
this.stopRequested = true;
|
|
@@ -19250,23 +19232,23 @@ class ResearchOrchestrator {
|
|
|
19250
19232
|
async startBrief(userQuery) {
|
|
19251
19233
|
const query = userQuery.trim();
|
|
19252
19234
|
if (!query) {
|
|
19253
|
-
logger$
|
|
19235
|
+
logger$j.warn("Ignoring empty Research Desk query");
|
|
19254
19236
|
return;
|
|
19255
19237
|
}
|
|
19256
19238
|
if (this.state.phase !== "idle") {
|
|
19257
|
-
logger$
|
|
19239
|
+
logger$j.warn("Research already in progress, ignoring startBrief");
|
|
19258
19240
|
return;
|
|
19259
19241
|
}
|
|
19260
19242
|
this.state = this.initialState();
|
|
19261
19243
|
this.state.originalQuery = query;
|
|
19262
19244
|
this.state.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19263
19245
|
this.setPhase("briefing");
|
|
19264
|
-
logger$
|
|
19246
|
+
logger$j.info(`Brief started for query: ${query.slice(0, 120)}`);
|
|
19265
19247
|
}
|
|
19266
19248
|
// ── phase: briefing → planning ─────────────────────────────────
|
|
19267
19249
|
confirmBrief() {
|
|
19268
19250
|
if (this.state.phase !== "briefing") {
|
|
19269
|
-
logger$
|
|
19251
|
+
logger$j.warn("Not in briefing phase, ignoring confirmBrief");
|
|
19270
19252
|
return;
|
|
19271
19253
|
}
|
|
19272
19254
|
this.setPhase("planning");
|
|
@@ -19274,7 +19256,7 @@ class ResearchOrchestrator {
|
|
|
19274
19256
|
// ── phase: planning → awaiting_approval ────────────────────────
|
|
19275
19257
|
setObjectives(objectives) {
|
|
19276
19258
|
if (this.state.phase !== "planning") {
|
|
19277
|
-
logger$
|
|
19259
|
+
logger$j.warn("Not in planning phase, ignoring setObjectives");
|
|
19278
19260
|
return;
|
|
19279
19261
|
}
|
|
19280
19262
|
const threads = objectives.threads.slice(0, MAX_THREADS).map(mergeBlockedSourceDomains);
|
|
@@ -19303,11 +19285,11 @@ class ResearchOrchestrator {
|
|
|
19303
19285
|
try {
|
|
19304
19286
|
const parsed = JSON.parse(json);
|
|
19305
19287
|
if (typeof parsed.researchQuestion !== "string" || !parsed.researchQuestion.trim()) {
|
|
19306
|
-
logger$
|
|
19288
|
+
logger$j.warn("Missing researchQuestion in objectives JSON");
|
|
19307
19289
|
return false;
|
|
19308
19290
|
}
|
|
19309
19291
|
if (!Array.isArray(parsed.threads) || parsed.threads.length === 0) {
|
|
19310
|
-
logger$
|
|
19292
|
+
logger$j.warn("Missing or empty threads array in objectives JSON");
|
|
19311
19293
|
return false;
|
|
19312
19294
|
}
|
|
19313
19295
|
const threads = parsed.threads.map((t, i) => {
|
|
@@ -19325,7 +19307,7 @@ class ResearchOrchestrator {
|
|
|
19325
19307
|
};
|
|
19326
19308
|
}).filter((thread) => thread.question && thread.searchQueries.length > 0).slice(0, MAX_THREADS);
|
|
19327
19309
|
if (threads.length === 0) {
|
|
19328
|
-
logger$
|
|
19310
|
+
logger$j.warn("Objectives JSON did not contain any valid research threads");
|
|
19329
19311
|
return false;
|
|
19330
19312
|
}
|
|
19331
19313
|
const objectives = {
|
|
@@ -19336,17 +19318,17 @@ class ResearchOrchestrator {
|
|
|
19336
19318
|
totalSourceBudget: threads.reduce((sum, t) => sum + t.sourceBudget, 0)
|
|
19337
19319
|
};
|
|
19338
19320
|
this.setObjectives(objectives);
|
|
19339
|
-
logger$
|
|
19321
|
+
logger$j.info(`Parsed ${objectives.threads.length} threads from objectives`);
|
|
19340
19322
|
return true;
|
|
19341
19323
|
} catch (err) {
|
|
19342
|
-
logger$
|
|
19324
|
+
logger$j.warn("Failed to parse objectives JSON", err);
|
|
19343
19325
|
return false;
|
|
19344
19326
|
}
|
|
19345
19327
|
}
|
|
19346
19328
|
// ── phase: awaiting_approval → executing ───────────────────────
|
|
19347
19329
|
approveObjectives(mode, includeTraces) {
|
|
19348
19330
|
if (this.state.phase !== "awaiting_approval") {
|
|
19349
|
-
logger$
|
|
19331
|
+
logger$j.warn("Not awaiting approval, ignoring approveObjectives");
|
|
19350
19332
|
return;
|
|
19351
19333
|
}
|
|
19352
19334
|
if (mode) this.state.supervisionMode = mode;
|
|
@@ -19381,7 +19363,7 @@ class ResearchOrchestrator {
|
|
|
19381
19363
|
this.state.threads.map((thread) => {
|
|
19382
19364
|
if (this.state.phase !== "executing") return null;
|
|
19383
19365
|
return this.runSubAgent(thread, tabMutex).catch((err) => {
|
|
19384
|
-
logger$
|
|
19366
|
+
logger$j.error(`Sub-agent "${thread.label}" failed`, err);
|
|
19385
19367
|
return {
|
|
19386
19368
|
threadLabel: thread.label,
|
|
19387
19369
|
threadQuestion: thread.question,
|
|
@@ -19410,7 +19392,7 @@ class ResearchOrchestrator {
|
|
|
19410
19392
|
try {
|
|
19411
19393
|
await this.synthesizeReport();
|
|
19412
19394
|
} catch (err) {
|
|
19413
|
-
logger$
|
|
19395
|
+
logger$j.error("Auto-synthesis failed", err);
|
|
19414
19396
|
this.state.error = `Synthesis failed: ${String(err)}`;
|
|
19415
19397
|
this.setPhase("delivered");
|
|
19416
19398
|
}
|
|
@@ -19521,7 +19503,7 @@ Start by searching for: ${thread.searchQueries.join(" or ")}`;
|
|
|
19521
19503
|
try {
|
|
19522
19504
|
this.tabManager.closeTab(tabId);
|
|
19523
19505
|
} catch (err) {
|
|
19524
|
-
logger$
|
|
19506
|
+
logger$j.warn(`Failed to close sub-agent tab ${tabId}`, err);
|
|
19525
19507
|
}
|
|
19526
19508
|
}
|
|
19527
19509
|
}
|
|
@@ -19530,7 +19512,7 @@ Start by searching for: ${thread.searchQueries.join(" or ")}`;
|
|
|
19530
19512
|
try {
|
|
19531
19513
|
claims = await this.extractClaimsFromTranscript(thread, transcript);
|
|
19532
19514
|
} catch (err) {
|
|
19533
|
-
logger$
|
|
19515
|
+
logger$j.warn(`Claim extraction failed for "${thread.label}"`, err);
|
|
19534
19516
|
}
|
|
19535
19517
|
}
|
|
19536
19518
|
if (this.state.phase === "executing" && this.state.includeTraces) {
|
|
@@ -19620,7 +19602,7 @@ ${transcript.slice(0, 32e3)}`;
|
|
|
19620
19602
|
(claim) => claim.claim && claim.sourceUrl && claim.extractedQuote
|
|
19621
19603
|
);
|
|
19622
19604
|
} catch {
|
|
19623
|
-
logger$
|
|
19605
|
+
logger$j.warn(`Failed to parse claims JSON for "${thread.label}"`);
|
|
19624
19606
|
return [];
|
|
19625
19607
|
}
|
|
19626
19608
|
}
|
|
@@ -19705,7 +19687,7 @@ ${transcript.slice(0, 32e3)}`;
|
|
|
19705
19687
|
objectives
|
|
19706
19688
|
};
|
|
19707
19689
|
} catch (err) {
|
|
19708
|
-
logger$
|
|
19690
|
+
logger$j.warn("Failed to parse synthesis JSON, using sourced fallback report", err);
|
|
19709
19691
|
return buildFallbackReport(objectives, findings, String(err));
|
|
19710
19692
|
}
|
|
19711
19693
|
}
|
|
@@ -20252,7 +20234,7 @@ function loadRenderers(chromeView, sidebarView, devtoolsPanelView) {
|
|
|
20252
20234
|
});
|
|
20253
20235
|
}
|
|
20254
20236
|
}
|
|
20255
|
-
const logger$
|
|
20237
|
+
const logger$i = createLogger("PrivateWindow");
|
|
20256
20238
|
const privateWindows = /* @__PURE__ */ new Set();
|
|
20257
20239
|
function layoutPrivateViews(state2) {
|
|
20258
20240
|
const { window: win, chromeView, tabManager } = state2;
|
|
@@ -20473,7 +20455,7 @@ function createPrivateWindow() {
|
|
|
20473
20455
|
privateSession.clearStorageData(),
|
|
20474
20456
|
privateSession.clearCache()
|
|
20475
20457
|
]).catch((error) => {
|
|
20476
|
-
logger$
|
|
20458
|
+
logger$i.warn("Failed to clear private browsing session:", error);
|
|
20477
20459
|
});
|
|
20478
20460
|
});
|
|
20479
20461
|
privateWindows.add(state2);
|
|
@@ -20483,7 +20465,7 @@ function createPrivateWindow() {
|
|
|
20483
20465
|
});
|
|
20484
20466
|
loadPrivateRenderer(chromeView);
|
|
20485
20467
|
win.show();
|
|
20486
|
-
logger$
|
|
20468
|
+
logger$i.info("Private browsing window opened");
|
|
20487
20469
|
return state2;
|
|
20488
20470
|
}
|
|
20489
20471
|
const window$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
@@ -20857,7 +20839,7 @@ function registerTabHandlers(windowState2, _sendToRendererViews) {
|
|
|
20857
20839
|
});
|
|
20858
20840
|
}
|
|
20859
20841
|
const require$1 = node_module.createRequire(require("url").pathToFileURL(__filename).href);
|
|
20860
|
-
const logger$
|
|
20842
|
+
const logger$h = createLogger("DevTrace");
|
|
20861
20843
|
let cachedFactory;
|
|
20862
20844
|
function createNoopTraceSession() {
|
|
20863
20845
|
return {
|
|
@@ -20890,7 +20872,7 @@ function loadLocalFactory() {
|
|
|
20890
20872
|
return cachedFactory;
|
|
20891
20873
|
}
|
|
20892
20874
|
} catch (err) {
|
|
20893
|
-
logger$
|
|
20875
|
+
logger$h.warn("Failed to load local trace logger:", err);
|
|
20894
20876
|
}
|
|
20895
20877
|
}
|
|
20896
20878
|
return cachedFactory;
|
|
@@ -21682,9 +21664,6 @@ function renderReaderContent(page) {
|
|
|
21682
21664
|
}
|
|
21683
21665
|
return source.split(/\n{2,}/).map((block) => block.trim()).filter(Boolean).map((block) => `<p>${escapeHtml(block).replace(/\n/g, "<br>")}</p>`).join("\n");
|
|
21684
21666
|
}
|
|
21685
|
-
function escapeHtml(str) {
|
|
21686
|
-
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
21687
|
-
}
|
|
21688
21667
|
function registerContentHandlers(windowState2) {
|
|
21689
21668
|
const { tabManager } = windowState2;
|
|
21690
21669
|
electron.ipcMain.handle(Channels.CONTENT_EXTRACT, async (event) => {
|
|
@@ -21721,7 +21700,7 @@ function registerContentHandlers(windowState2) {
|
|
|
21721
21700
|
return windowState2.uiState.focusMode;
|
|
21722
21701
|
});
|
|
21723
21702
|
}
|
|
21724
|
-
const logger$
|
|
21703
|
+
const logger$g = createLogger("HighlightIPC");
|
|
21725
21704
|
function registerHighlightHandlers(windowState2, sendToRendererViews) {
|
|
21726
21705
|
const { tabManager, chromeView } = windowState2;
|
|
21727
21706
|
const getActiveHighlightCountSafe = async () => {
|
|
@@ -21730,7 +21709,7 @@ function registerHighlightHandlers(windowState2, sendToRendererViews) {
|
|
|
21730
21709
|
try {
|
|
21731
21710
|
return await getHighlightCount(info.wc) ?? 0;
|
|
21732
21711
|
} catch (err) {
|
|
21733
|
-
logger$
|
|
21712
|
+
logger$g.warn("Failed to get active highlight count:", err);
|
|
21734
21713
|
return 0;
|
|
21735
21714
|
}
|
|
21736
21715
|
};
|
|
@@ -21755,13 +21734,13 @@ function registerHighlightHandlers(windowState2, sendToRendererViews) {
|
|
|
21755
21734
|
const result = await captureSelectionHighlight(wc);
|
|
21756
21735
|
if (result.success && result.text) {
|
|
21757
21736
|
await highlightOnPage(wc, null, result.text, void 0, void 0, "yellow").catch(
|
|
21758
|
-
(err) => logger$
|
|
21737
|
+
(err) => logger$g.warn("Failed to highlight captured selection:", err)
|
|
21759
21738
|
);
|
|
21760
21739
|
await emitHighlightCount();
|
|
21761
21740
|
}
|
|
21762
21741
|
return result;
|
|
21763
21742
|
} catch (err) {
|
|
21764
|
-
logger$
|
|
21743
|
+
logger$g.warn("Failed to capture highlight from active tab:", err);
|
|
21765
21744
|
return { success: false, message: "Could not capture selection" };
|
|
21766
21745
|
}
|
|
21767
21746
|
});
|
|
@@ -21778,7 +21757,7 @@ function registerHighlightHandlers(windowState2, sendToRendererViews) {
|
|
|
21778
21757
|
}
|
|
21779
21758
|
});
|
|
21780
21759
|
} catch (err) {
|
|
21781
|
-
logger$
|
|
21760
|
+
logger$g.warn("Failed to persist auto-highlight selection:", err);
|
|
21782
21761
|
}
|
|
21783
21762
|
});
|
|
21784
21763
|
electron.ipcMain.handle(Channels.HIGHLIGHT_NAV_COUNT, (event) => {
|
|
@@ -21792,7 +21771,7 @@ function registerHighlightHandlers(windowState2, sendToRendererViews) {
|
|
|
21792
21771
|
try {
|
|
21793
21772
|
return scrollToHighlight(info.wc, index);
|
|
21794
21773
|
} catch (err) {
|
|
21795
|
-
logger$
|
|
21774
|
+
logger$g.warn("Failed to scroll to highlight:", err);
|
|
21796
21775
|
return false;
|
|
21797
21776
|
}
|
|
21798
21777
|
});
|
|
@@ -21807,7 +21786,7 @@ function registerHighlightHandlers(windowState2, sendToRendererViews) {
|
|
|
21807
21786
|
}
|
|
21808
21787
|
return removed;
|
|
21809
21788
|
} catch (err) {
|
|
21810
|
-
logger$
|
|
21789
|
+
logger$g.warn("Failed to remove highlight at index:", err);
|
|
21811
21790
|
return false;
|
|
21812
21791
|
}
|
|
21813
21792
|
});
|
|
@@ -21822,7 +21801,7 @@ function registerHighlightHandlers(windowState2, sendToRendererViews) {
|
|
|
21822
21801
|
}
|
|
21823
21802
|
return cleared;
|
|
21824
21803
|
} catch (err) {
|
|
21825
|
-
logger$
|
|
21804
|
+
logger$g.warn("Failed to clear highlight elements:", err);
|
|
21826
21805
|
return false;
|
|
21827
21806
|
}
|
|
21828
21807
|
});
|
|
@@ -22791,7 +22770,7 @@ Exception: ${result.exceptionDetails}`);
|
|
|
22791
22770
|
}
|
|
22792
22771
|
);
|
|
22793
22772
|
}
|
|
22794
|
-
const logger$
|
|
22773
|
+
const logger$f = createLogger("MCP");
|
|
22795
22774
|
function asTextResponse(text) {
|
|
22796
22775
|
return { content: [{ type: "text", text }] };
|
|
22797
22776
|
}
|
|
@@ -22892,7 +22871,7 @@ async function getPostActionState(tabManager, name) {
|
|
|
22892
22871
|
}
|
|
22893
22872
|
}
|
|
22894
22873
|
} catch (err) {
|
|
22895
|
-
logger$
|
|
22874
|
+
logger$f.warn("Failed to compute post-action state warning:", err);
|
|
22896
22875
|
}
|
|
22897
22876
|
return `${warning}
|
|
22898
22877
|
[state: url=${wc.getURL()}, canGoBack=${tab.canGoBack()}, canGoForward=${tab.canGoForward()}, loading=${wc.isLoading()}]`;
|
|
@@ -22997,7 +22976,7 @@ async function waitForConditionMcp(wc, text, selector, timeoutMs) {
|
|
|
22997
22976
|
}
|
|
22998
22977
|
})()
|
|
22999
22978
|
`).catch((err) => {
|
|
23000
|
-
logger$
|
|
22979
|
+
logger$f.warn("Failed to gather wait_for timeout diagnostic:", err);
|
|
23001
22980
|
return null;
|
|
23002
22981
|
});
|
|
23003
22982
|
if (typeof diagnostic === "string" && diagnostic.trim()) {
|
|
@@ -23483,6 +23462,7 @@ function registerBookmarkTools(server, tabManager, runtime2) {
|
|
|
23483
23462
|
return `Opened bookmark "${bookmark.title}" in new tab ${createdId}`;
|
|
23484
23463
|
}
|
|
23485
23464
|
const activeId = tabManager.getActiveTabId();
|
|
23465
|
+
if (!activeId) return "No active tab to open bookmark in";
|
|
23486
23466
|
const activeTab = tabManager.getActiveTab();
|
|
23487
23467
|
tabManager.navigateTab(activeId, bookmark.url);
|
|
23488
23468
|
if (activeTab) {
|
|
@@ -23713,7 +23693,7 @@ function registerSessionTools(server, tabManager, runtime2) {
|
|
|
23713
23693
|
)
|
|
23714
23694
|
);
|
|
23715
23695
|
}
|
|
23716
|
-
const logger$
|
|
23696
|
+
const logger$e = createLogger("VaultShared");
|
|
23717
23697
|
const ALGORITHM = "aes-256-gcm";
|
|
23718
23698
|
const IV_LENGTH = 12;
|
|
23719
23699
|
const AUTH_TAG_LENGTH = 16;
|
|
@@ -23807,7 +23787,7 @@ function createVaultIO(vaultFilename, encrypt2, decrypt2) {
|
|
|
23807
23787
|
cachedEntries = JSON.parse(json);
|
|
23808
23788
|
return cachedEntries;
|
|
23809
23789
|
} catch (err) {
|
|
23810
|
-
logger$
|
|
23790
|
+
logger$e.error("Failed to load vault:", err);
|
|
23811
23791
|
throw new Error("Could not unlock the vault. Check OS secret storage availability.");
|
|
23812
23792
|
}
|
|
23813
23793
|
}
|
|
@@ -23890,7 +23870,7 @@ function createAuditLog(filename, maxEntries) {
|
|
|
23890
23870
|
} catch {
|
|
23891
23871
|
}
|
|
23892
23872
|
} catch (err) {
|
|
23893
|
-
logger$
|
|
23873
|
+
logger$e.error("Failed to write audit log:", err);
|
|
23894
23874
|
}
|
|
23895
23875
|
}
|
|
23896
23876
|
function readAuditLog2(limit = 100) {
|
|
@@ -23900,7 +23880,7 @@ function createAuditLog(filename, maxEntries) {
|
|
|
23900
23880
|
const lines = fs$1.readFileSync(auditPath, "utf-8").split("\n").filter((l) => l.trim());
|
|
23901
23881
|
return lines.slice(-Math.min(limit, maxEntries)).map((line) => JSON.parse(line)).reverse();
|
|
23902
23882
|
} catch (err) {
|
|
23903
|
-
logger$
|
|
23883
|
+
logger$e.error("Failed to read audit log:", err);
|
|
23904
23884
|
return [];
|
|
23905
23885
|
}
|
|
23906
23886
|
}
|
|
@@ -23973,9 +23953,12 @@ async function requestConsent(request) {
|
|
|
23973
23953
|
if (sessionTrustedDomains.has(domain)) {
|
|
23974
23954
|
return { approved: true, trustForSession: true };
|
|
23975
23955
|
}
|
|
23976
|
-
const
|
|
23956
|
+
const parentWindow = electron.BrowserWindow.getFocusedWindow() ?? electron.BrowserWindow.getAllWindows()[0];
|
|
23957
|
+
if (!parentWindow) {
|
|
23958
|
+
return { approved: false, trustForSession: false };
|
|
23959
|
+
}
|
|
23977
23960
|
const { response } = await electron.dialog.showMessageBox(
|
|
23978
|
-
|
|
23961
|
+
parentWindow,
|
|
23979
23962
|
{
|
|
23980
23963
|
type: "question",
|
|
23981
23964
|
title: "Agent Credential Access",
|
|
@@ -24004,7 +23987,7 @@ async function requestConsent(request) {
|
|
|
24004
23987
|
}
|
|
24005
23988
|
const AUDIT_FILENAME = "vessel-vault-audit.jsonl";
|
|
24006
23989
|
const MAX_ENTRIES = 1e3;
|
|
24007
|
-
const logger$
|
|
23990
|
+
const logger$d = createLogger("VaultAudit");
|
|
24008
23991
|
function getAuditPath() {
|
|
24009
23992
|
return path$1.join(electron.app.getPath("userData"), AUDIT_FILENAME);
|
|
24010
23993
|
}
|
|
@@ -24018,7 +24001,7 @@ function appendAuditEntry(entry) {
|
|
|
24018
24001
|
});
|
|
24019
24002
|
fs$1.chmodSync(auditPath, 384);
|
|
24020
24003
|
} catch (err) {
|
|
24021
|
-
logger$
|
|
24004
|
+
logger$d.error("Failed to write audit log:", err);
|
|
24022
24005
|
}
|
|
24023
24006
|
}
|
|
24024
24007
|
function readAuditLog$1(limit = 100) {
|
|
@@ -24028,7 +24011,7 @@ function readAuditLog$1(limit = 100) {
|
|
|
24028
24011
|
const lines = fs$1.readFileSync(auditPath, "utf-8").split("\n").filter((l) => l.trim());
|
|
24029
24012
|
return lines.slice(-Math.min(limit, MAX_ENTRIES)).map((line) => JSON.parse(line)).reverse();
|
|
24030
24013
|
} catch (err) {
|
|
24031
|
-
logger$
|
|
24014
|
+
logger$d.error("Failed to read audit log:", err);
|
|
24032
24015
|
return [];
|
|
24033
24016
|
}
|
|
24034
24017
|
}
|
|
@@ -24198,7 +24181,7 @@ const mcpRuntimeState = {
|
|
|
24198
24181
|
httpServer: null,
|
|
24199
24182
|
authToken: null
|
|
24200
24183
|
};
|
|
24201
|
-
const logger$
|
|
24184
|
+
const logger$c = createLogger("MCP");
|
|
24202
24185
|
const MCP_AUTH_FILENAME = "mcp-auth.json";
|
|
24203
24186
|
function getMcpAuthFilePath() {
|
|
24204
24187
|
const configDir = process.env.VESSEL_CONFIG_DIR || path$1.join(
|
|
@@ -24235,7 +24218,7 @@ function writeMcpAuthFile(endpoint, token) {
|
|
|
24235
24218
|
);
|
|
24236
24219
|
fs$1.chmodSync(filePath2, 384);
|
|
24237
24220
|
} catch (err) {
|
|
24238
|
-
logger$
|
|
24221
|
+
logger$c.warn("Failed to write auth file:", err);
|
|
24239
24222
|
}
|
|
24240
24223
|
}
|
|
24241
24224
|
function clearMcpAuthFile() {
|
|
@@ -24261,7 +24244,7 @@ function clearMcpAuthFile() {
|
|
|
24261
24244
|
);
|
|
24262
24245
|
fs$1.chmodSync(filePath2, 384);
|
|
24263
24246
|
} catch (err) {
|
|
24264
|
-
logger$
|
|
24247
|
+
logger$c.warn("Failed to clear auth file:", err);
|
|
24265
24248
|
}
|
|
24266
24249
|
}
|
|
24267
24250
|
function regenerateMcpAuthToken() {
|
|
@@ -24271,7 +24254,7 @@ function regenerateMcpAuthToken() {
|
|
|
24271
24254
|
writeMcpAuthFile(endpoint, mcpRuntimeState.authToken);
|
|
24272
24255
|
return { endpoint };
|
|
24273
24256
|
}
|
|
24274
|
-
const logger$
|
|
24257
|
+
const logger$b = createLogger("MCP");
|
|
24275
24258
|
function registerTools(server, tabManager, runtime2) {
|
|
24276
24259
|
server.registerPrompt(
|
|
24277
24260
|
"vessel-supervisor-brief",
|
|
@@ -24350,7 +24333,7 @@ function registerTools(server, tabManager, runtime2) {
|
|
|
24350
24333
|
const page = await extractContent$1(wc);
|
|
24351
24334
|
pageType = detectPageType(page);
|
|
24352
24335
|
} catch (err) {
|
|
24353
|
-
logger$
|
|
24336
|
+
logger$b.warn("Failed to detect page type for tool scoring, falling back to GENERAL:", err);
|
|
24354
24337
|
}
|
|
24355
24338
|
}
|
|
24356
24339
|
const scored = TOOL_DEFINITIONS.map((def) => {
|
|
@@ -24608,6 +24591,7 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
24608
24591
|
}
|
|
24609
24592
|
return withAction(runtime2, tabManager, "navigate", { url }, async () => {
|
|
24610
24593
|
const id = tabManager.getActiveTabId();
|
|
24594
|
+
if (!id) return asNoActiveTabResponse();
|
|
24611
24595
|
const navError = tabManager.navigateTab(id, url, postBody);
|
|
24612
24596
|
if (navError) return navError;
|
|
24613
24597
|
const { httpStatus } = await waitForLoadWithStatus(
|
|
@@ -24731,7 +24715,9 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
24731
24715
|
return "No previous page in history";
|
|
24732
24716
|
}
|
|
24733
24717
|
const beforeUrl = tab.view.webContents.getURL();
|
|
24734
|
-
tabManager.
|
|
24718
|
+
const backId = tabManager.getActiveTabId();
|
|
24719
|
+
if (!backId) return asNoActiveTabResponse();
|
|
24720
|
+
tabManager.goBack(backId);
|
|
24735
24721
|
await waitForLoad(tab.view.webContents);
|
|
24736
24722
|
const afterUrl = tab.view.webContents.getURL();
|
|
24737
24723
|
return afterUrl !== beforeUrl ? `Went back to ${afterUrl}` : `Back action completed but page stayed on ${afterUrl}`;
|
|
@@ -24752,7 +24738,9 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
24752
24738
|
return "No forward page in history";
|
|
24753
24739
|
}
|
|
24754
24740
|
const beforeUrl = tab.view.webContents.getURL();
|
|
24755
|
-
tabManager.
|
|
24741
|
+
const forwardId = tabManager.getActiveTabId();
|
|
24742
|
+
if (!forwardId) return asNoActiveTabResponse();
|
|
24743
|
+
tabManager.goForward(forwardId);
|
|
24756
24744
|
await waitForLoad(tab.view.webContents);
|
|
24757
24745
|
const afterUrl = tab.view.webContents.getURL();
|
|
24758
24746
|
return afterUrl !== beforeUrl ? `Went forward to ${afterUrl}` : `Forward action completed but page stayed on ${afterUrl}`;
|
|
@@ -24769,7 +24757,9 @@ ${buildScopedContext(pageContent, mode)}`;
|
|
|
24769
24757
|
const tab = tabManager.getActiveTab();
|
|
24770
24758
|
if (!tab) return asNoActiveTabResponse();
|
|
24771
24759
|
return withAction(runtime2, tabManager, "reload", {}, async () => {
|
|
24772
|
-
tabManager.
|
|
24760
|
+
const reloadId = tabManager.getActiveTabId();
|
|
24761
|
+
if (!reloadId) return asNoActiveTabResponse();
|
|
24762
|
+
tabManager.reloadTab(reloadId);
|
|
24773
24763
|
await waitForLoad(tab.view.webContents);
|
|
24774
24764
|
return `Reloaded ${tab.view.webContents.getURL()}`;
|
|
24775
24765
|
});
|
|
@@ -25638,7 +25628,7 @@ ${JSON.stringify(otherHighlights, null, 2)}`
|
|
|
25638
25628
|
void 0,
|
|
25639
25629
|
h.color
|
|
25640
25630
|
).catch(
|
|
25641
|
-
(err) => logger$
|
|
25631
|
+
(err) => logger$b.warn("Failed to restore highlight after removal:", err)
|
|
25642
25632
|
);
|
|
25643
25633
|
}
|
|
25644
25634
|
}
|
|
@@ -25905,7 +25895,7 @@ ${flow.steps.map((s, i) => ` ${i === 0 ? "→" : " "} ${s.label}`).join("\n")}`
|
|
|
25905
25895
|
try {
|
|
25906
25896
|
page = await extractContent$1(wc);
|
|
25907
25897
|
} catch (err) {
|
|
25908
|
-
logger$
|
|
25898
|
+
logger$b.warn("Failed to extract page while generating suggestions:", err);
|
|
25909
25899
|
return asTextResponse(
|
|
25910
25900
|
"Could not read page. Try navigate to a working URL."
|
|
25911
25901
|
);
|
|
@@ -26079,6 +26069,7 @@ ${results.join("\n")}`;
|
|
|
26079
26069
|
const steps = [];
|
|
26080
26070
|
if (url) {
|
|
26081
26071
|
const id = tabManager.getActiveTabId();
|
|
26072
|
+
if (!id) return asNoActiveTabResponse();
|
|
26082
26073
|
tabManager.navigateTab(id, url);
|
|
26083
26074
|
await waitForLoad(wc);
|
|
26084
26075
|
steps.push(`Navigated to ${wc.getURL()}`);
|
|
@@ -26515,7 +26506,7 @@ ${JSON.stringify(tableJson, null, 2)}`;
|
|
|
26515
26506
|
try {
|
|
26516
26507
|
targetDomain = new URL(tab.state.url).hostname;
|
|
26517
26508
|
} catch (err) {
|
|
26518
|
-
logger$
|
|
26509
|
+
logger$b.warn("Failed to parse active tab URL for vault_status:", err);
|
|
26519
26510
|
return asErrorTextResponse("Could not parse active tab URL");
|
|
26520
26511
|
}
|
|
26521
26512
|
}
|
|
@@ -26583,7 +26574,7 @@ Use vault_login to fill the login form. Credentials are filled directly — you
|
|
|
26583
26574
|
try {
|
|
26584
26575
|
hostname = new URL(tab.state.url).hostname;
|
|
26585
26576
|
} catch (err) {
|
|
26586
|
-
logger$
|
|
26577
|
+
logger$b.warn("Failed to parse active tab URL for vault_login:", err);
|
|
26587
26578
|
return asErrorTextResponse("Could not parse active tab URL");
|
|
26588
26579
|
}
|
|
26589
26580
|
const matches = findEntriesForDomain(`https://${hostname}`);
|
|
@@ -26679,7 +26670,7 @@ Use vault_login to fill the login form. Credentials are filled directly — you
|
|
|
26679
26670
|
try {
|
|
26680
26671
|
hostname = new URL(tab.state.url).hostname;
|
|
26681
26672
|
} catch (err) {
|
|
26682
|
-
logger$
|
|
26673
|
+
logger$b.warn("Failed to parse active tab URL for vault_totp:", err);
|
|
26683
26674
|
return asErrorTextResponse("Could not parse active tab URL");
|
|
26684
26675
|
}
|
|
26685
26676
|
const matches = findEntriesForDomain(`https://${hostname}`);
|
|
@@ -27027,7 +27018,7 @@ function startMcpServer(tabManager, runtime2, port) {
|
|
|
27027
27018
|
await mcpServer.connect(transport);
|
|
27028
27019
|
await transport.handleRequest(req, res);
|
|
27029
27020
|
} catch (error) {
|
|
27030
|
-
logger$
|
|
27021
|
+
logger$b.error("Error handling request:", error);
|
|
27031
27022
|
if (!res.headersSent) {
|
|
27032
27023
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
27033
27024
|
res.end(
|
|
@@ -27046,7 +27037,7 @@ function startMcpServer(tabManager, runtime2, port) {
|
|
|
27046
27037
|
};
|
|
27047
27038
|
server.once("error", (error) => {
|
|
27048
27039
|
const message = error.code === "EADDRINUSE" ? `Port ${port} is already in use. MCP server not started.` : error.message;
|
|
27049
|
-
logger$
|
|
27040
|
+
logger$b.error("Server error:", error);
|
|
27050
27041
|
clearMcpAuthFile();
|
|
27051
27042
|
setMcpHealth({
|
|
27052
27043
|
configuredPort: port,
|
|
@@ -27078,7 +27069,7 @@ function startMcpServer(tabManager, runtime2, port) {
|
|
|
27078
27069
|
message: `MCP server listening on ${endpoint}.`
|
|
27079
27070
|
});
|
|
27080
27071
|
if (process.env.VESSEL_DEBUG_MCP === "1" || process.env.VESSEL_DEBUG_MCP === "true") {
|
|
27081
|
-
logger$
|
|
27072
|
+
logger$b.info(`Server listening on ${endpoint} (auth enabled)`);
|
|
27082
27073
|
}
|
|
27083
27074
|
if (mcpRuntimeState.authToken) {
|
|
27084
27075
|
writeMcpAuthFile(endpoint, mcpRuntimeState.authToken);
|
|
@@ -27117,12 +27108,13 @@ function stopMcpServer() {
|
|
|
27117
27108
|
message: "MCP server is stopped."
|
|
27118
27109
|
});
|
|
27119
27110
|
if (process.env.VESSEL_DEBUG_MCP === "1" || process.env.VESSEL_DEBUG_MCP === "true") {
|
|
27120
|
-
logger$
|
|
27111
|
+
logger$b.info("Server stopped");
|
|
27121
27112
|
}
|
|
27122
27113
|
resolve();
|
|
27123
27114
|
});
|
|
27124
27115
|
});
|
|
27125
27116
|
}
|
|
27117
|
+
const logger$a = createLogger("Feedback");
|
|
27126
27118
|
const SUPPORT_API = process.env.VESSEL_SUPPORT_API || process.env.VESSEL_PREMIUM_API || "https://vesselpremium.quantaintellect.com";
|
|
27127
27119
|
const MAX_FEEDBACK_MESSAGE_LENGTH = 5e3;
|
|
27128
27120
|
const FEEDBACK_REQUEST_TIMEOUT_MS = 15e3;
|
|
@@ -27158,7 +27150,11 @@ async function submitFeedback(payload) {
|
|
|
27158
27150
|
source: payload.source
|
|
27159
27151
|
})
|
|
27160
27152
|
});
|
|
27161
|
-
const data = await
|
|
27153
|
+
const data = await readJsonResponse(
|
|
27154
|
+
res,
|
|
27155
|
+
{},
|
|
27156
|
+
(msg) => logger$a.warn("Failed to parse feedback response:", msg)
|
|
27157
|
+
);
|
|
27162
27158
|
if (!res.ok) {
|
|
27163
27159
|
return errorResult(data.error || `HTTP ${res.status}`);
|
|
27164
27160
|
}
|
|
@@ -29480,12 +29476,14 @@ function renderReportAsMarkdown(report, traces) {
|
|
|
29480
29476
|
}
|
|
29481
29477
|
const logger$4 = createLogger("ResearchIPC");
|
|
29482
29478
|
function registerResearchHandlers(getOrchestrator) {
|
|
29483
|
-
electron.ipcMain.handle(Channels.RESEARCH_STATE_GET, () => {
|
|
29479
|
+
electron.ipcMain.handle(Channels.RESEARCH_STATE_GET, (event) => {
|
|
29480
|
+
assertTrustedIpcSender(event);
|
|
29484
29481
|
return getOrchestrator().getState();
|
|
29485
29482
|
});
|
|
29486
29483
|
electron.ipcMain.handle(
|
|
29487
29484
|
Channels.RESEARCH_START_BRIEF,
|
|
29488
|
-
async (
|
|
29485
|
+
async (event, query) => {
|
|
29486
|
+
assertTrustedIpcSender(event);
|
|
29489
29487
|
try {
|
|
29490
29488
|
const trimmedQuery = query.trim();
|
|
29491
29489
|
if (!trimmedQuery) {
|
|
@@ -29502,7 +29500,8 @@ function registerResearchHandlers(getOrchestrator) {
|
|
|
29502
29500
|
}
|
|
29503
29501
|
}
|
|
29504
29502
|
);
|
|
29505
|
-
electron.ipcMain.handle(Channels.RESEARCH_CONFIRM_BRIEF, () => {
|
|
29503
|
+
electron.ipcMain.handle(Channels.RESEARCH_CONFIRM_BRIEF, (event) => {
|
|
29504
|
+
assertTrustedIpcSender(event);
|
|
29506
29505
|
try {
|
|
29507
29506
|
if (isToolGated("research_confirm_brief")) {
|
|
29508
29507
|
return { accepted: false, reason: "premium" };
|
|
@@ -29520,7 +29519,8 @@ function registerResearchHandlers(getOrchestrator) {
|
|
|
29520
29519
|
});
|
|
29521
29520
|
electron.ipcMain.handle(
|
|
29522
29521
|
Channels.RESEARCH_APPROVE_OBJECTIVES,
|
|
29523
|
-
(
|
|
29522
|
+
(event, options) => {
|
|
29523
|
+
assertTrustedIpcSender(event);
|
|
29524
29524
|
try {
|
|
29525
29525
|
if (isToolGated("research_approve_objectives")) {
|
|
29526
29526
|
return { accepted: false, reason: "premium" };
|
|
@@ -29546,23 +29546,28 @@ function registerResearchHandlers(getOrchestrator) {
|
|
|
29546
29546
|
);
|
|
29547
29547
|
electron.ipcMain.handle(
|
|
29548
29548
|
Channels.RESEARCH_SET_MODE,
|
|
29549
|
-
(
|
|
29549
|
+
(event, mode) => {
|
|
29550
|
+
assertTrustedIpcSender(event);
|
|
29550
29551
|
getOrchestrator().setSupervisionMode(mode);
|
|
29551
29552
|
}
|
|
29552
29553
|
);
|
|
29553
29554
|
electron.ipcMain.handle(
|
|
29554
29555
|
Channels.RESEARCH_SET_TRACES,
|
|
29555
|
-
(
|
|
29556
|
+
(event, include) => {
|
|
29557
|
+
assertTrustedIpcSender(event);
|
|
29556
29558
|
getOrchestrator().setIncludeTraces(include);
|
|
29557
29559
|
}
|
|
29558
29560
|
);
|
|
29559
|
-
electron.ipcMain.handle(Channels.RESEARCH_CANCEL, () => {
|
|
29561
|
+
electron.ipcMain.handle(Channels.RESEARCH_CANCEL, (event) => {
|
|
29562
|
+
assertTrustedIpcSender(event);
|
|
29560
29563
|
getOrchestrator().cancel();
|
|
29561
29564
|
});
|
|
29562
|
-
electron.ipcMain.handle(Channels.RESEARCH_STOP_AND_SYNTHESIZE, () => {
|
|
29565
|
+
electron.ipcMain.handle(Channels.RESEARCH_STOP_AND_SYNTHESIZE, (event) => {
|
|
29566
|
+
assertTrustedIpcSender(event);
|
|
29563
29567
|
getOrchestrator().stopAndSynthesizeCurrentFindings();
|
|
29564
29568
|
});
|
|
29565
|
-
electron.ipcMain.handle(Channels.RESEARCH_EXPORT_REPORT, async () => {
|
|
29569
|
+
electron.ipcMain.handle(Channels.RESEARCH_EXPORT_REPORT, async (event) => {
|
|
29570
|
+
assertTrustedIpcSender(event);
|
|
29566
29571
|
try {
|
|
29567
29572
|
if (isToolGated("research_export_report")) {
|
|
29568
29573
|
return { accepted: false, reason: "premium" };
|