@quanta-intellect/vessel-browser 0.1.94 → 0.1.95
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
|
@@ -276,9 +276,10 @@ function persistNow() {
|
|
|
276
276
|
return fs.promises.mkdir(path.dirname(getSettingsPath()), { recursive: true }).then(
|
|
277
277
|
() => fs.promises.writeFile(
|
|
278
278
|
getSettingsPath(),
|
|
279
|
-
JSON.stringify(buildPersistedSettings(settings), null, 2)
|
|
279
|
+
JSON.stringify(buildPersistedSettings(settings), null, 2),
|
|
280
|
+
{ encoding: "utf-8", mode: 384 }
|
|
280
281
|
)
|
|
281
|
-
).catch((err) => logger$n.error("Failed to save settings:", err));
|
|
282
|
+
).then(() => fs.promises.chmod(getSettingsPath(), 384).catch(() => void 0)).catch((err) => logger$n.error("Failed to save settings:", err));
|
|
282
283
|
}
|
|
283
284
|
function saveSettings() {
|
|
284
285
|
saveDirty = true;
|
|
@@ -1133,7 +1134,7 @@ function createDebouncedJsonPersistence({
|
|
|
1133
1134
|
data,
|
|
1134
1135
|
typeof data === "string" ? { encoding: "utf-8", mode: 384 } : { mode: 384 }
|
|
1135
1136
|
)
|
|
1136
|
-
).catch((err) => logger$l.error(`Failed to save ${logLabel}:`, err));
|
|
1137
|
+
).then(() => fs.promises.chmod(filePath2, 384).catch(() => void 0)).catch((err) => logger$l.error(`Failed to save ${logLabel}:`, err));
|
|
1137
1138
|
};
|
|
1138
1139
|
const schedule = () => {
|
|
1139
1140
|
saveDirty2 = true;
|
|
@@ -4760,6 +4761,21 @@ const POSTHOG_HOST = process.env.POSTHOG_HOST || "https://us.i.posthog.com";
|
|
|
4760
4761
|
const BATCH_INTERVAL_MS = 6e4;
|
|
4761
4762
|
const MAX_BATCH_SIZE = 50;
|
|
4762
4763
|
const SENSITIVE_PROPERTY_RE = /url|uri|query|prompt|content|text|token|secret|key|password|credential|email|domain/i;
|
|
4764
|
+
const SENSITIVE_STRING_VALUE_RE = /https?:\/\/|www\.|[^\s@]+@[^\s@]+\.[^\s@]+|bearer\s+\S+|eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.|(?:sk|pk|rk|gh[pousr]|xox[baprs])-[-_A-Za-z0-9]{12,}/i;
|
|
4765
|
+
const EMPTY_PROPERTY_ALLOWLIST = /* @__PURE__ */ new Set();
|
|
4766
|
+
const TELEMETRY_PROPERTY_ALLOWLIST = {
|
|
4767
|
+
app_launched: /* @__PURE__ */ new Set(["electron_version", "chrome_version"]),
|
|
4768
|
+
app_session_ended: /* @__PURE__ */ new Set(["duration_minutes"]),
|
|
4769
|
+
tool_called: /* @__PURE__ */ new Set(["tool_name", "page_type"]),
|
|
4770
|
+
provider_configured: /* @__PURE__ */ new Set(["provider_id"]),
|
|
4771
|
+
page_type_detected: /* @__PURE__ */ new Set(["page_type"]),
|
|
4772
|
+
setting_changed: /* @__PURE__ */ new Set(["setting_key"]),
|
|
4773
|
+
approval_mode_changed: /* @__PURE__ */ new Set(["mode"]),
|
|
4774
|
+
bookmark_action: /* @__PURE__ */ new Set(["action"]),
|
|
4775
|
+
vault_action: /* @__PURE__ */ new Set(["action"]),
|
|
4776
|
+
extraction_failed: /* @__PURE__ */ new Set(["reason"]),
|
|
4777
|
+
premium_funnel: /* @__PURE__ */ new Set(["step", "status", "reason"])
|
|
4778
|
+
};
|
|
4763
4779
|
function getDeviceIdPath() {
|
|
4764
4780
|
return path.join(electron.app.getPath("userData"), ".vessel-device-id");
|
|
4765
4781
|
}
|
|
@@ -4775,7 +4791,8 @@ function getDeviceId() {
|
|
|
4775
4791
|
deviceId = crypto$1.randomUUID();
|
|
4776
4792
|
try {
|
|
4777
4793
|
fs.mkdirSync(path.dirname(idPath), { recursive: true });
|
|
4778
|
-
fs.writeFileSync(idPath, deviceId, "utf-8");
|
|
4794
|
+
fs.writeFileSync(idPath, deviceId, { encoding: "utf-8", mode: 384 });
|
|
4795
|
+
fs.chmodSync(idPath, 384);
|
|
4779
4796
|
} catch {
|
|
4780
4797
|
}
|
|
4781
4798
|
return deviceId;
|
|
@@ -4788,11 +4805,15 @@ function isEnabled() {
|
|
|
4788
4805
|
if (process.env.VESSEL_DEV === "1") return false;
|
|
4789
4806
|
return loadSettings().telemetryEnabled !== false;
|
|
4790
4807
|
}
|
|
4791
|
-
function sanitizeTelemetryProperties(properties) {
|
|
4808
|
+
function sanitizeTelemetryProperties(properties, allowedKeys) {
|
|
4792
4809
|
const safe = {};
|
|
4793
4810
|
for (const [key2, value] of Object.entries(properties)) {
|
|
4794
|
-
if (
|
|
4811
|
+
if (allowedKeys && !allowedKeys.has(key2)) continue;
|
|
4812
|
+
if (!allowedKeys?.has(key2) && SENSITIVE_PROPERTY_RE.test(key2)) continue;
|
|
4795
4813
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null) {
|
|
4814
|
+
if (typeof value === "string" && SENSITIVE_STRING_VALUE_RE.test(value)) {
|
|
4815
|
+
continue;
|
|
4816
|
+
}
|
|
4796
4817
|
safe[key2] = typeof value === "string" ? value.slice(0, 120) : value;
|
|
4797
4818
|
}
|
|
4798
4819
|
}
|
|
@@ -4800,10 +4821,11 @@ function sanitizeTelemetryProperties(properties) {
|
|
|
4800
4821
|
}
|
|
4801
4822
|
function trackEvent(event, properties = {}) {
|
|
4802
4823
|
if (!isEnabled()) return;
|
|
4824
|
+
const allowedKeys = TELEMETRY_PROPERTY_ALLOWLIST[event] ?? EMPTY_PROPERTY_ALLOWLIST;
|
|
4803
4825
|
eventQueue.push({
|
|
4804
4826
|
event,
|
|
4805
4827
|
properties: {
|
|
4806
|
-
...sanitizeTelemetryProperties(properties),
|
|
4828
|
+
...sanitizeTelemetryProperties(properties, allowedKeys),
|
|
4807
4829
|
premium_status: isPremium() ? "premium" : "free",
|
|
4808
4830
|
app_version: electron.app.getVersion(),
|
|
4809
4831
|
platform: process.platform,
|
|
@@ -6986,7 +7008,7 @@ function isClickReadLoop(names) {
|
|
|
6986
7008
|
return clickReadPairs >= 2;
|
|
6987
7009
|
}
|
|
6988
7010
|
const ANTHROPIC_MAX_TOKENS = 4096;
|
|
6989
|
-
function isRecord(value) {
|
|
7011
|
+
function isRecord$1(value) {
|
|
6990
7012
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6991
7013
|
}
|
|
6992
7014
|
function anthropicModelLikelySupportsThinking(model) {
|
|
@@ -7110,7 +7132,7 @@ class AnthropicProvider {
|
|
|
7110
7132
|
} else if (event.type === "content_block_stop" && currentToolUse) {
|
|
7111
7133
|
try {
|
|
7112
7134
|
const input = JSON.parse(currentToolUse.inputJson || "{}");
|
|
7113
|
-
if (!isRecord(input)) {
|
|
7135
|
+
if (!isRecord$1(input)) {
|
|
7114
7136
|
throw new Error("Tool input must be a JSON object");
|
|
7115
7137
|
}
|
|
7116
7138
|
toolUseBlocks.push({
|
|
@@ -8523,6 +8545,9 @@ async function openExternalAllowlisted(url, rule) {
|
|
|
8523
8545
|
if (!schemes.includes(parsed.protocol)) {
|
|
8524
8546
|
throw new Error(`Blocked external URL scheme: ${parsed.protocol}`);
|
|
8525
8547
|
}
|
|
8548
|
+
if (parsed.username || parsed.password) {
|
|
8549
|
+
throw new Error("Blocked external URL with embedded credentials");
|
|
8550
|
+
}
|
|
8526
8551
|
if (rule.hosts && !rule.hosts.includes(parsed.hostname)) {
|
|
8527
8552
|
throw new Error(`Blocked external URL host: ${parsed.hostname}`);
|
|
8528
8553
|
}
|
|
@@ -8593,54 +8618,6 @@ function parseTokenExpiry(accessToken) {
|
|
|
8593
8618
|
}
|
|
8594
8619
|
return Date.now() + 36e5;
|
|
8595
8620
|
}
|
|
8596
|
-
async function exchangeIdTokenForApiKey(idToken) {
|
|
8597
|
-
const body = new URLSearchParams({
|
|
8598
|
-
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
|
|
8599
|
-
client_id: CLIENT_ID,
|
|
8600
|
-
requested_token: "openai-api-key",
|
|
8601
|
-
subject_token: idToken,
|
|
8602
|
-
subject_token_type: "urn:ietf:params:oauth:token-type:id_token"
|
|
8603
|
-
});
|
|
8604
|
-
const response = await fetch(`${ISSUER}/oauth/token`, {
|
|
8605
|
-
method: "POST",
|
|
8606
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
8607
|
-
body: body.toString()
|
|
8608
|
-
});
|
|
8609
|
-
if (!response.ok) {
|
|
8610
|
-
let errorMsg = `OpenAI API token exchange failed: ${response.status}`;
|
|
8611
|
-
try {
|
|
8612
|
-
const err = await response.json();
|
|
8613
|
-
if (typeof err.error_description === "string") {
|
|
8614
|
-
errorMsg = err.error_description;
|
|
8615
|
-
} else if (typeof err.error === "string") {
|
|
8616
|
-
errorMsg = err.error;
|
|
8617
|
-
}
|
|
8618
|
-
} catch {
|
|
8619
|
-
}
|
|
8620
|
-
throw new Error(errorMsg);
|
|
8621
|
-
}
|
|
8622
|
-
const data = await response.json();
|
|
8623
|
-
if (!data.access_token) {
|
|
8624
|
-
throw new Error("OpenAI API token exchange did not return an access token");
|
|
8625
|
-
}
|
|
8626
|
-
return data.access_token;
|
|
8627
|
-
}
|
|
8628
|
-
async function ensureCodexApiKey(tokens) {
|
|
8629
|
-
if (tokens.apiKey) return tokens;
|
|
8630
|
-
if (!tokens.idToken) return tokens;
|
|
8631
|
-
try {
|
|
8632
|
-
return {
|
|
8633
|
-
...tokens,
|
|
8634
|
-
apiKey: await exchangeIdTokenForApiKey(tokens.idToken)
|
|
8635
|
-
};
|
|
8636
|
-
} catch (err) {
|
|
8637
|
-
logger$g.warn(
|
|
8638
|
-
"Codex API-key token exchange failed; continuing with ChatGPT OAuth tokens:",
|
|
8639
|
-
err
|
|
8640
|
-
);
|
|
8641
|
-
return tokens;
|
|
8642
|
-
}
|
|
8643
|
-
}
|
|
8644
8621
|
async function exchangeCodeForTokens(code, redirectUri, codeVerifier) {
|
|
8645
8622
|
const body = new URLSearchParams({
|
|
8646
8623
|
grant_type: "authorization_code",
|
|
@@ -8678,7 +8655,7 @@ async function exchangeCodeForTokens(code, redirectUri, codeVerifier) {
|
|
|
8678
8655
|
accountId: claims?.accountId || "",
|
|
8679
8656
|
accountEmail: claims?.email
|
|
8680
8657
|
};
|
|
8681
|
-
return
|
|
8658
|
+
return tokens;
|
|
8682
8659
|
}
|
|
8683
8660
|
async function refreshAccessToken(tokens) {
|
|
8684
8661
|
const body = new URLSearchParams({
|
|
@@ -8714,7 +8691,7 @@ async function refreshAccessToken(tokens) {
|
|
|
8714
8691
|
accountId: claims?.accountId || tokens.accountId || "",
|
|
8715
8692
|
accountEmail: claims?.email || tokens.accountEmail
|
|
8716
8693
|
};
|
|
8717
|
-
return
|
|
8694
|
+
return refreshedTokens;
|
|
8718
8695
|
}
|
|
8719
8696
|
function startServer(port, pkce, expectedState, resolve, reject) {
|
|
8720
8697
|
const server = http.createServer(async (req, res) => {
|
|
@@ -8885,12 +8862,57 @@ const logger$f = createLogger("CodexProvider");
|
|
|
8885
8862
|
const REFRESH_WINDOW_MS = 5 * 60 * 1e3;
|
|
8886
8863
|
const CODEX_BACKEND_BASE_URL = "https://chatgpt.com/backend-api/codex";
|
|
8887
8864
|
const CODEX_CLIENT_VERSION = "0.129.0";
|
|
8865
|
+
function isRecord(value) {
|
|
8866
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8867
|
+
}
|
|
8868
|
+
async function createCodexFunctionCallOutput(functionCall, availableToolNames, onChunk, onToolCall) {
|
|
8869
|
+
const callId = functionCall.call_id || functionCall.id || "";
|
|
8870
|
+
const name = functionCall.name || "";
|
|
8871
|
+
if (!callId) {
|
|
8872
|
+
return {
|
|
8873
|
+
type: "function_call_output",
|
|
8874
|
+
call_id: callId,
|
|
8875
|
+
output: "Error: Function call was missing a call_id. Please retry the tool call."
|
|
8876
|
+
};
|
|
8877
|
+
}
|
|
8878
|
+
if (!name || !availableToolNames.has(name)) {
|
|
8879
|
+
onChunk(`
|
|
8880
|
+
<<tool:${name || "unknown"}:⚠ unsupported>>
|
|
8881
|
+
`);
|
|
8882
|
+
return {
|
|
8883
|
+
type: "function_call_output",
|
|
8884
|
+
call_id: callId,
|
|
8885
|
+
output: `Error: Unsupported tool${name ? `: ${name}` : ""}. Use one of the provided tools.`
|
|
8886
|
+
};
|
|
8887
|
+
}
|
|
8888
|
+
let args;
|
|
8889
|
+
try {
|
|
8890
|
+
const parsed = JSON.parse(functionCall.arguments || "{}");
|
|
8891
|
+
if (!isRecord(parsed)) throw new Error("Tool arguments must be a JSON object");
|
|
8892
|
+
args = parsed;
|
|
8893
|
+
} catch {
|
|
8894
|
+
onChunk(`
|
|
8895
|
+
<<tool:${name}:⚠ invalid args>>
|
|
8896
|
+
`);
|
|
8897
|
+
return {
|
|
8898
|
+
type: "function_call_output",
|
|
8899
|
+
call_id: callId,
|
|
8900
|
+
output: "Error: Invalid JSON in tool arguments. Please retry with a valid JSON object."
|
|
8901
|
+
};
|
|
8902
|
+
}
|
|
8903
|
+
const output = await onToolCall(name, args);
|
|
8904
|
+
return {
|
|
8905
|
+
type: "function_call_output",
|
|
8906
|
+
call_id: callId,
|
|
8907
|
+
output
|
|
8908
|
+
};
|
|
8909
|
+
}
|
|
8888
8910
|
class CodexProvider {
|
|
8889
8911
|
agentToolProfile;
|
|
8890
8912
|
tokens;
|
|
8891
8913
|
model;
|
|
8892
8914
|
abortController = null;
|
|
8893
|
-
constructor(tokens, model
|
|
8915
|
+
constructor(tokens, model) {
|
|
8894
8916
|
this.tokens = tokens;
|
|
8895
8917
|
this.model = model;
|
|
8896
8918
|
this.agentToolProfile = "default";
|
|
@@ -8909,7 +8931,7 @@ class CodexProvider {
|
|
|
8909
8931
|
);
|
|
8910
8932
|
}
|
|
8911
8933
|
}
|
|
8912
|
-
backendHeaders() {
|
|
8934
|
+
backendHeaders(turnState) {
|
|
8913
8935
|
const headers = {
|
|
8914
8936
|
Authorization: `Bearer ${this.tokens.accessToken}`,
|
|
8915
8937
|
"Content-Type": "application/json",
|
|
@@ -8920,6 +8942,9 @@ class CodexProvider {
|
|
|
8920
8942
|
if (this.tokens.accountId) {
|
|
8921
8943
|
headers["ChatGPT-Account-ID"] = this.tokens.accountId;
|
|
8922
8944
|
}
|
|
8945
|
+
if (turnState) {
|
|
8946
|
+
headers["x-codex-turn-state"] = turnState;
|
|
8947
|
+
}
|
|
8923
8948
|
return headers;
|
|
8924
8949
|
}
|
|
8925
8950
|
buildInput(userMessage, history) {
|
|
@@ -8928,7 +8953,7 @@ class CodexProvider {
|
|
|
8928
8953
|
input.push({
|
|
8929
8954
|
type: "message",
|
|
8930
8955
|
role: msg.role,
|
|
8931
|
-
content: [{ type: "input_text", text: msg.content }]
|
|
8956
|
+
content: [{ type: msg.role === "assistant" ? "output_text" : "input_text", text: msg.content }]
|
|
8932
8957
|
});
|
|
8933
8958
|
}
|
|
8934
8959
|
input.push({
|
|
@@ -8938,7 +8963,7 @@ class CodexProvider {
|
|
|
8938
8963
|
});
|
|
8939
8964
|
return input;
|
|
8940
8965
|
}
|
|
8941
|
-
handleStreamEvent(raw, onChunk,
|
|
8966
|
+
handleStreamEvent(raw, onChunk, acc) {
|
|
8942
8967
|
if (!raw.trim() || raw.trim() === "[DONE]") return;
|
|
8943
8968
|
let event;
|
|
8944
8969
|
try {
|
|
@@ -8947,13 +8972,28 @@ class CodexProvider {
|
|
|
8947
8972
|
return;
|
|
8948
8973
|
}
|
|
8949
8974
|
if (event.type === "response.output_text.delta" && event.delta) {
|
|
8950
|
-
emittedTextFromDelta
|
|
8975
|
+
acc.emittedTextFromDelta = true;
|
|
8976
|
+
acc.text += event.delta;
|
|
8951
8977
|
onChunk(event.delta);
|
|
8952
8978
|
return;
|
|
8953
8979
|
}
|
|
8954
|
-
if (event.type === "response.
|
|
8955
|
-
const
|
|
8956
|
-
if (
|
|
8980
|
+
if (event.type === "response.function_call_arguments.delta" && event.delta) {
|
|
8981
|
+
const key2 = event.call_id || event.item_id || "";
|
|
8982
|
+
if (key2) {
|
|
8983
|
+
acc.functionCallArgs.set(key2, (acc.functionCallArgs.get(key2) || "") + event.delta);
|
|
8984
|
+
}
|
|
8985
|
+
return;
|
|
8986
|
+
}
|
|
8987
|
+
if (event.type === "response.output_item.done" && event.item) {
|
|
8988
|
+
const item = event.item;
|
|
8989
|
+
if (item.type === "function_call") {
|
|
8990
|
+
const key2 = item.call_id || item.id || "";
|
|
8991
|
+
const args = acc.functionCallArgs.get(key2) || item.arguments || "";
|
|
8992
|
+
acc.functionCallArgs.delete(key2);
|
|
8993
|
+
acc.items.push({ ...item, arguments: args });
|
|
8994
|
+
} else if (item.type === "message") {
|
|
8995
|
+
acc.items.push(item);
|
|
8996
|
+
}
|
|
8957
8997
|
return;
|
|
8958
8998
|
}
|
|
8959
8999
|
if (event.type === "response.failed") {
|
|
@@ -8962,18 +9002,12 @@ class CodexProvider {
|
|
|
8962
9002
|
throw new Error(message);
|
|
8963
9003
|
}
|
|
8964
9004
|
}
|
|
8965
|
-
async streamCodexResponse(
|
|
9005
|
+
async streamCodexResponse(requestBody, onChunk, turnState) {
|
|
8966
9006
|
const response = await fetch(`${CODEX_BACKEND_BASE_URL}/responses`, {
|
|
8967
9007
|
method: "POST",
|
|
8968
|
-
headers: this.backendHeaders(),
|
|
9008
|
+
headers: this.backendHeaders(turnState),
|
|
8969
9009
|
signal: this.abortController?.signal,
|
|
8970
|
-
body: JSON.stringify(
|
|
8971
|
-
model: this.model,
|
|
8972
|
-
instructions: systemPrompt,
|
|
8973
|
-
input: this.buildInput(userMessage, history),
|
|
8974
|
-
stream: true,
|
|
8975
|
-
store: false
|
|
8976
|
-
})
|
|
9010
|
+
body: JSON.stringify(requestBody)
|
|
8977
9011
|
});
|
|
8978
9012
|
if (!response.ok) {
|
|
8979
9013
|
const text = await response.text().catch(() => "");
|
|
@@ -8984,33 +9018,53 @@ class CodexProvider {
|
|
|
8984
9018
|
if (!response.body) {
|
|
8985
9019
|
throw new Error("Codex backend returned an empty response stream");
|
|
8986
9020
|
}
|
|
9021
|
+
const newTurnState = response.headers.get("x-codex-turn-state") || null;
|
|
8987
9022
|
const reader = response.body.getReader();
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
|
|
8993
|
-
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
|
|
9023
|
+
try {
|
|
9024
|
+
const decoder = new TextDecoder();
|
|
9025
|
+
let buffer = "";
|
|
9026
|
+
const acc = {
|
|
9027
|
+
text: "",
|
|
9028
|
+
items: [],
|
|
9029
|
+
emittedTextFromDelta: false,
|
|
9030
|
+
functionCallArgs: /* @__PURE__ */ new Map()
|
|
9031
|
+
};
|
|
9032
|
+
while (true) {
|
|
9033
|
+
const { value, done } = await reader.read();
|
|
9034
|
+
if (done) break;
|
|
9035
|
+
buffer += decoder.decode(value, { stream: true });
|
|
9036
|
+
let separatorIndex;
|
|
9037
|
+
while ((separatorIndex = buffer.indexOf("\n\n")) !== -1) {
|
|
9038
|
+
const block = buffer.slice(0, separatorIndex);
|
|
9039
|
+
buffer = buffer.slice(separatorIndex + 2);
|
|
9040
|
+
const data = block.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
|
|
9041
|
+
this.handleStreamEvent(data, onChunk, acc);
|
|
9042
|
+
}
|
|
9043
|
+
}
|
|
9044
|
+
const trailing = buffer.trim();
|
|
9045
|
+
if (trailing) {
|
|
9046
|
+
const data = trailing.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
|
|
9047
|
+
this.handleStreamEvent(data, onChunk, acc);
|
|
9048
|
+
}
|
|
9049
|
+
return { text: acc.text, items: acc.items, turnState: newTurnState };
|
|
9050
|
+
} finally {
|
|
9051
|
+
reader.releaseLock();
|
|
9007
9052
|
}
|
|
9008
9053
|
}
|
|
9009
9054
|
async streamQuery(systemPrompt, userMessage, onChunk, onEnd, history) {
|
|
9010
9055
|
await this.ensureFreshTokens();
|
|
9011
9056
|
this.abortController = new AbortController();
|
|
9012
9057
|
try {
|
|
9013
|
-
await this.streamCodexResponse(
|
|
9058
|
+
await this.streamCodexResponse(
|
|
9059
|
+
{
|
|
9060
|
+
model: this.model,
|
|
9061
|
+
instructions: systemPrompt,
|
|
9062
|
+
input: this.buildInput(userMessage, history),
|
|
9063
|
+
stream: true,
|
|
9064
|
+
store: false
|
|
9065
|
+
},
|
|
9066
|
+
onChunk
|
|
9067
|
+
);
|
|
9014
9068
|
} catch (err) {
|
|
9015
9069
|
if (err.name !== "AbortError") {
|
|
9016
9070
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -9024,11 +9078,59 @@ class CodexProvider {
|
|
|
9024
9078
|
onEnd();
|
|
9025
9079
|
}
|
|
9026
9080
|
}
|
|
9027
|
-
async streamAgentQuery(systemPrompt, userMessage,
|
|
9081
|
+
async streamAgentQuery(systemPrompt, userMessage, tools, onChunk, onToolCall, onEnd, history) {
|
|
9028
9082
|
await this.ensureFreshTokens();
|
|
9029
9083
|
this.abortController = new AbortController();
|
|
9084
|
+
const maxIterations = getEffectiveMaxIterations();
|
|
9085
|
+
const availableToolNames = new Set(tools.map((tool) => tool.name));
|
|
9086
|
+
let iterationsUsed = 0;
|
|
9087
|
+
const convertedTools = tools.map((tool) => ({
|
|
9088
|
+
type: "function",
|
|
9089
|
+
name: tool.name,
|
|
9090
|
+
description: tool.description || "",
|
|
9091
|
+
parameters: tool.input_schema
|
|
9092
|
+
}));
|
|
9093
|
+
let currentInput = this.buildInput(userMessage, history);
|
|
9094
|
+
let turnState = null;
|
|
9030
9095
|
try {
|
|
9031
|
-
|
|
9096
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
9097
|
+
iterationsUsed = i + 1;
|
|
9098
|
+
const result = await this.streamCodexResponse(
|
|
9099
|
+
{
|
|
9100
|
+
model: this.model,
|
|
9101
|
+
instructions: systemPrompt,
|
|
9102
|
+
input: currentInput,
|
|
9103
|
+
tools: convertedTools,
|
|
9104
|
+
stream: true,
|
|
9105
|
+
store: false
|
|
9106
|
+
},
|
|
9107
|
+
onChunk,
|
|
9108
|
+
turnState || void 0
|
|
9109
|
+
);
|
|
9110
|
+
turnState = result.turnState || turnState;
|
|
9111
|
+
const functionCalls = result.items.filter(
|
|
9112
|
+
(item) => item.type === "function_call"
|
|
9113
|
+
);
|
|
9114
|
+
if (functionCalls.length === 0) {
|
|
9115
|
+
break;
|
|
9116
|
+
}
|
|
9117
|
+
currentInput = [];
|
|
9118
|
+
for (const fc of functionCalls) {
|
|
9119
|
+
currentInput.push(
|
|
9120
|
+
await createCodexFunctionCallOutput(
|
|
9121
|
+
fc,
|
|
9122
|
+
availableToolNames,
|
|
9123
|
+
onChunk,
|
|
9124
|
+
onToolCall
|
|
9125
|
+
)
|
|
9126
|
+
);
|
|
9127
|
+
}
|
|
9128
|
+
}
|
|
9129
|
+
if (iterationsUsed >= maxIterations) {
|
|
9130
|
+
onChunk(`
|
|
9131
|
+
|
|
9132
|
+
[Reached maximum tool call limit (${maxIterations} steps). You can adjust this in Settings → Max Tool Iterations, or continue by sending another message.]`);
|
|
9133
|
+
}
|
|
9032
9134
|
} catch (err) {
|
|
9033
9135
|
if (err.name !== "AbortError") {
|
|
9034
9136
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -9112,11 +9214,11 @@ function buildLlamaCppCtxWarning(ctxSize) {
|
|
|
9112
9214
|
}
|
|
9113
9215
|
async function fetchCodexBackendModels(tokens) {
|
|
9114
9216
|
const url = new URL("https://chatgpt.com/backend-api/codex/models");
|
|
9115
|
-
url.searchParams.set("client_version",
|
|
9217
|
+
url.searchParams.set("client_version", CODEX_CLIENT_VERSION);
|
|
9116
9218
|
const headers = {
|
|
9117
9219
|
Authorization: `Bearer ${tokens.accessToken}`,
|
|
9118
9220
|
originator: "codex_cli_rs",
|
|
9119
|
-
"User-Agent":
|
|
9221
|
+
"User-Agent": `codex_cli_rs/${CODEX_CLIENT_VERSION} Vessel`
|
|
9120
9222
|
};
|
|
9121
9223
|
if (tokens.accountId) {
|
|
9122
9224
|
headers["ChatGPT-Account-ID"] = tokens.accountId;
|
|
@@ -9219,7 +9321,7 @@ function createProvider(config) {
|
|
|
9219
9321
|
"OpenAI Codex requires authentication. Open settings to connect your ChatGPT account."
|
|
9220
9322
|
);
|
|
9221
9323
|
}
|
|
9222
|
-
return new CodexProvider(tokens, normalized.model
|
|
9324
|
+
return new CodexProvider(tokens, normalized.model);
|
|
9223
9325
|
}
|
|
9224
9326
|
return new OpenAICompatProvider(normalized);
|
|
9225
9327
|
}
|
|
@@ -19524,6 +19626,16 @@ const logger$b = createLogger("VaultShared");
|
|
|
19524
19626
|
const ALGORITHM = "aes-256-gcm";
|
|
19525
19627
|
const IV_LENGTH = 12;
|
|
19526
19628
|
const AUTH_TAG_LENGTH = 16;
|
|
19629
|
+
const KEY_STORAGE_PREFIX = "base64:";
|
|
19630
|
+
function encodeEncryptionKeyForStorage(key2) {
|
|
19631
|
+
return `${KEY_STORAGE_PREFIX}${key2.toString("base64")}`;
|
|
19632
|
+
}
|
|
19633
|
+
function decodeEncryptionKeyFromStorage(value) {
|
|
19634
|
+
if (value.startsWith(KEY_STORAGE_PREFIX)) {
|
|
19635
|
+
return Buffer.from(value.slice(KEY_STORAGE_PREFIX.length), "base64");
|
|
19636
|
+
}
|
|
19637
|
+
return Buffer.from(value, "utf-8");
|
|
19638
|
+
}
|
|
19527
19639
|
function assertSecretStorageAvailable(customMessage) {
|
|
19528
19640
|
if (!electron.safeStorage.isEncryptionAvailable()) {
|
|
19529
19641
|
throw new Error(
|
|
@@ -19536,11 +19648,17 @@ function getOrCreateEncryptionKey(keyFilename) {
|
|
|
19536
19648
|
const keyPath = path$1.join(electron.app.getPath("userData"), keyFilename);
|
|
19537
19649
|
if (fs$1.existsSync(keyPath)) {
|
|
19538
19650
|
const encryptedKey = fs$1.readFileSync(keyPath);
|
|
19539
|
-
|
|
19651
|
+
const key22 = decodeEncryptionKeyFromStorage(
|
|
19652
|
+
electron.safeStorage.decryptString(encryptedKey)
|
|
19653
|
+
);
|
|
19654
|
+
if (key22.length !== 32) {
|
|
19655
|
+
throw new Error("Stored vault encryption key has an invalid length.");
|
|
19656
|
+
}
|
|
19657
|
+
return key22;
|
|
19540
19658
|
}
|
|
19541
19659
|
const key2 = crypto$2.randomBytes(32);
|
|
19542
19660
|
fs$1.mkdirSync(path$1.dirname(keyPath), { recursive: true });
|
|
19543
|
-
const encrypted = electron.safeStorage.encryptString(key2
|
|
19661
|
+
const encrypted = electron.safeStorage.encryptString(encodeEncryptionKeyForStorage(key2));
|
|
19544
19662
|
fs$1.writeFileSync(keyPath, encrypted, { mode: 384 });
|
|
19545
19663
|
fs$1.chmodSync(keyPath, 384);
|
|
19546
19664
|
return key2;
|
|
@@ -19607,7 +19725,7 @@ function createVaultIO(vaultFilename, encrypt2, decrypt2) {
|
|
|
19607
19725
|
const encrypted = encrypt2(json);
|
|
19608
19726
|
const vaultPath = getVaultPath();
|
|
19609
19727
|
fs$1.mkdirSync(path$1.dirname(vaultPath), { recursive: true });
|
|
19610
|
-
fs$1.writeFileSync(vaultPath, encrypted);
|
|
19728
|
+
fs$1.writeFileSync(vaultPath, encrypted, { mode: 384 });
|
|
19611
19729
|
fs$1.chmodSync(vaultPath, 384);
|
|
19612
19730
|
cachedEntries = entries;
|
|
19613
19731
|
}
|
|
@@ -19663,12 +19781,20 @@ function createAuditLog(filename, maxEntries) {
|
|
|
19663
19781
|
try {
|
|
19664
19782
|
const auditPath = getAuditPath2();
|
|
19665
19783
|
fs$1.mkdirSync(path$1.dirname(auditPath), { recursive: true });
|
|
19666
|
-
fs$1.appendFileSync(auditPath, JSON.stringify(entry) + "\n"
|
|
19784
|
+
fs$1.appendFileSync(auditPath, JSON.stringify(entry) + "\n", {
|
|
19785
|
+
encoding: "utf-8",
|
|
19786
|
+
mode: 384
|
|
19787
|
+
});
|
|
19788
|
+
fs$1.chmodSync(auditPath, 384);
|
|
19667
19789
|
try {
|
|
19668
19790
|
const lines = fs$1.readFileSync(auditPath, "utf-8").split("\n").filter((l) => l.trim());
|
|
19669
19791
|
if (lines.length > maxEntries) {
|
|
19670
19792
|
const trimmed = lines.slice(-maxEntries);
|
|
19671
|
-
fs$1.writeFileSync(auditPath, trimmed.join("\n") + "\n"
|
|
19793
|
+
fs$1.writeFileSync(auditPath, trimmed.join("\n") + "\n", {
|
|
19794
|
+
encoding: "utf-8",
|
|
19795
|
+
mode: 384
|
|
19796
|
+
});
|
|
19797
|
+
fs$1.chmodSync(auditPath, 384);
|
|
19672
19798
|
}
|
|
19673
19799
|
} catch {
|
|
19674
19800
|
}
|
|
@@ -19795,7 +19921,11 @@ function appendAuditEntry(entry) {
|
|
|
19795
19921
|
try {
|
|
19796
19922
|
const auditPath = getAuditPath();
|
|
19797
19923
|
fs$1.mkdirSync(path$1.dirname(auditPath), { recursive: true });
|
|
19798
|
-
fs$1.appendFileSync(auditPath, JSON.stringify(entry) + "\n"
|
|
19924
|
+
fs$1.appendFileSync(auditPath, JSON.stringify(entry) + "\n", {
|
|
19925
|
+
encoding: "utf-8",
|
|
19926
|
+
mode: 384
|
|
19927
|
+
});
|
|
19928
|
+
fs$1.chmodSync(auditPath, 384);
|
|
19799
19929
|
} catch (err) {
|
|
19800
19930
|
logger$a.error("Failed to write audit log:", err);
|
|
19801
19931
|
}
|
|
@@ -20075,7 +20205,7 @@ function isDangerousMcpAction(name) {
|
|
|
20075
20205
|
}
|
|
20076
20206
|
function requiresExplicitMcpApproval(name, args) {
|
|
20077
20207
|
if (name === "delete_session" || name === "close_tab" || name === "load_session") return true;
|
|
20078
|
-
if (name === "
|
|
20208
|
+
if (name === "remove_bookmark_folder" && args.delete_contents === true) return true;
|
|
20079
20209
|
return false;
|
|
20080
20210
|
}
|
|
20081
20211
|
function getActiveTabSummary(tabManager) {
|
|
@@ -23909,6 +24039,43 @@ function uninstallKit(id, scheduledKitIds) {
|
|
|
23909
24039
|
return errorResult("Failed to remove the kit file.");
|
|
23910
24040
|
}
|
|
23911
24041
|
}
|
|
24042
|
+
const trustedIpcSenderIds = /* @__PURE__ */ new Set();
|
|
24043
|
+
function registerTrustedIpcSender(wc) {
|
|
24044
|
+
trustedIpcSenderIds.add(wc.id);
|
|
24045
|
+
wc.once("destroyed", () => trustedIpcSenderIds.delete(wc.id));
|
|
24046
|
+
}
|
|
24047
|
+
function assertTrustedIpcSender(event) {
|
|
24048
|
+
if (!trustedIpcSenderIds.has(event.sender.id)) {
|
|
24049
|
+
throw new Error("Blocked IPC from untrusted renderer");
|
|
24050
|
+
}
|
|
24051
|
+
}
|
|
24052
|
+
function isManagedTabIpcSender(event, tabManager) {
|
|
24053
|
+
return Boolean(tabManager.findTabByWebContentsId(event.sender.id));
|
|
24054
|
+
}
|
|
24055
|
+
function assertString(value, name) {
|
|
24056
|
+
if (typeof value !== "string") throw new Error(`${name} must be a string`);
|
|
24057
|
+
}
|
|
24058
|
+
function assertOptionalString(value, name) {
|
|
24059
|
+
if (value !== void 0 && typeof value !== "string") {
|
|
24060
|
+
throw new Error(`${name} must be a string`);
|
|
24061
|
+
}
|
|
24062
|
+
}
|
|
24063
|
+
function assertNumber(value, name) {
|
|
24064
|
+
if (typeof value !== "number" || Number.isNaN(value)) {
|
|
24065
|
+
throw new Error(`${name} must be a number`);
|
|
24066
|
+
}
|
|
24067
|
+
}
|
|
24068
|
+
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
24069
|
+
function isValidEmail(value) {
|
|
24070
|
+
return EMAIL_RE.test(value.trim());
|
|
24071
|
+
}
|
|
24072
|
+
function getActiveTabInfo(tabManager) {
|
|
24073
|
+
const tab = tabManager.getActiveTab();
|
|
24074
|
+
if (!tab) return null;
|
|
24075
|
+
const wc = tab.view.webContents;
|
|
24076
|
+
if (wc.isDestroyed()) return null;
|
|
24077
|
+
return { tab, wc };
|
|
24078
|
+
}
|
|
23912
24079
|
const logger$7 = createLogger("Scheduler");
|
|
23913
24080
|
let jobs = [];
|
|
23914
24081
|
let removeIdleListener = null;
|
|
@@ -23932,7 +24099,13 @@ function loadJobs() {
|
|
|
23932
24099
|
}
|
|
23933
24100
|
function saveJobs() {
|
|
23934
24101
|
try {
|
|
23935
|
-
|
|
24102
|
+
const jobsPath = getJobsPath();
|
|
24103
|
+
fs$1.mkdirSync(path$1.dirname(jobsPath), { recursive: true });
|
|
24104
|
+
fs$1.writeFileSync(jobsPath, JSON.stringify(jobs, null, 2), {
|
|
24105
|
+
encoding: "utf-8",
|
|
24106
|
+
mode: 384
|
|
24107
|
+
});
|
|
24108
|
+
fs$1.chmodSync(jobsPath, 384);
|
|
23936
24109
|
} catch (err) {
|
|
23937
24110
|
logger$7.warn("Failed to save jobs:", err);
|
|
23938
24111
|
}
|
|
@@ -24136,8 +24309,12 @@ function registerScheduleHandlers(windowState, runtime2, sendToAll) {
|
|
|
24136
24309
|
tick(windowState, runtime2);
|
|
24137
24310
|
setInterval(() => tick(windowState, runtime2), 6e4);
|
|
24138
24311
|
}, msToNextMinute);
|
|
24139
|
-
electron.ipcMain.handle(Channels.SCHEDULE_GET_ALL, () =>
|
|
24140
|
-
|
|
24312
|
+
electron.ipcMain.handle(Channels.SCHEDULE_GET_ALL, (event) => {
|
|
24313
|
+
assertTrustedIpcSender(event);
|
|
24314
|
+
return jobs;
|
|
24315
|
+
});
|
|
24316
|
+
electron.ipcMain.handle(Channels.SCHEDULE_CREATE, (event, rawJob) => {
|
|
24317
|
+
assertTrustedIpcSender(event);
|
|
24141
24318
|
if (!isValidJobData(rawJob)) {
|
|
24142
24319
|
throw new Error(
|
|
24143
24320
|
"Invalid job data. Required: kitId, kitName, kitIcon, renderedPrompt, schedule, enabled."
|
|
@@ -24154,7 +24331,8 @@ function registerScheduleHandlers(windowState, runtime2, sendToAll) {
|
|
|
24154
24331
|
sendToAll(Channels.SCHEDULE_JOBS_UPDATE, jobs);
|
|
24155
24332
|
return newJob;
|
|
24156
24333
|
});
|
|
24157
|
-
electron.ipcMain.handle(Channels.SCHEDULE_UPDATE, (
|
|
24334
|
+
electron.ipcMain.handle(Channels.SCHEDULE_UPDATE, (event, id, updates) => {
|
|
24335
|
+
assertTrustedIpcSender(event);
|
|
24158
24336
|
if (typeof id !== "string") throw new Error("id must be a string");
|
|
24159
24337
|
const job = jobs.find((j) => j.id === id);
|
|
24160
24338
|
if (!job) return null;
|
|
@@ -24180,7 +24358,8 @@ function registerScheduleHandlers(windowState, runtime2, sendToAll) {
|
|
|
24180
24358
|
sendToAll(Channels.SCHEDULE_JOBS_UPDATE, jobs);
|
|
24181
24359
|
return job;
|
|
24182
24360
|
});
|
|
24183
|
-
electron.ipcMain.handle(Channels.SCHEDULE_DELETE, (
|
|
24361
|
+
electron.ipcMain.handle(Channels.SCHEDULE_DELETE, (event, id) => {
|
|
24362
|
+
assertTrustedIpcSender(event);
|
|
24184
24363
|
if (typeof id !== "string") throw new Error("id must be a string");
|
|
24185
24364
|
const before = jobs.length;
|
|
24186
24365
|
jobs = jobs.filter((j) => j.id !== id);
|
|
@@ -24190,40 +24369,6 @@ function registerScheduleHandlers(windowState, runtime2, sendToAll) {
|
|
|
24190
24369
|
return true;
|
|
24191
24370
|
});
|
|
24192
24371
|
}
|
|
24193
|
-
const trustedIpcSenderIds = /* @__PURE__ */ new Set();
|
|
24194
|
-
function registerTrustedIpcSender(wc) {
|
|
24195
|
-
trustedIpcSenderIds.add(wc.id);
|
|
24196
|
-
wc.once("destroyed", () => trustedIpcSenderIds.delete(wc.id));
|
|
24197
|
-
}
|
|
24198
|
-
function assertTrustedIpcSender(event) {
|
|
24199
|
-
if (!trustedIpcSenderIds.has(event.sender.id)) {
|
|
24200
|
-
throw new Error("Blocked IPC from untrusted renderer");
|
|
24201
|
-
}
|
|
24202
|
-
}
|
|
24203
|
-
function assertString(value, name) {
|
|
24204
|
-
if (typeof value !== "string") throw new Error(`${name} must be a string`);
|
|
24205
|
-
}
|
|
24206
|
-
function assertOptionalString(value, name) {
|
|
24207
|
-
if (value !== void 0 && typeof value !== "string") {
|
|
24208
|
-
throw new Error(`${name} must be a string`);
|
|
24209
|
-
}
|
|
24210
|
-
}
|
|
24211
|
-
function assertNumber(value, name) {
|
|
24212
|
-
if (typeof value !== "number" || Number.isNaN(value)) {
|
|
24213
|
-
throw new Error(`${name} must be a number`);
|
|
24214
|
-
}
|
|
24215
|
-
}
|
|
24216
|
-
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
24217
|
-
function isValidEmail(value) {
|
|
24218
|
-
return EMAIL_RE.test(value.trim());
|
|
24219
|
-
}
|
|
24220
|
-
function getActiveTabInfo(tabManager) {
|
|
24221
|
-
const tab = tabManager.getActiveTab();
|
|
24222
|
-
if (!tab) return null;
|
|
24223
|
-
const wc = tab.view.webContents;
|
|
24224
|
-
if (wc.isDestroyed()) return null;
|
|
24225
|
-
return { tab, wc };
|
|
24226
|
-
}
|
|
24227
24372
|
const SAVE_DEBOUNCE_MS = 250;
|
|
24228
24373
|
const PROFILE_FIELDS = [
|
|
24229
24374
|
"label",
|
|
@@ -24563,24 +24708,29 @@ function sanitizeAutofillUpdates(value) {
|
|
|
24563
24708
|
return updates;
|
|
24564
24709
|
}
|
|
24565
24710
|
function registerAutofillHandlers(windowState) {
|
|
24566
|
-
electron.ipcMain.handle(Channels.AUTOFILL_LIST, () => {
|
|
24711
|
+
electron.ipcMain.handle(Channels.AUTOFILL_LIST, (event) => {
|
|
24712
|
+
assertTrustedIpcSender(event);
|
|
24567
24713
|
return listProfiles();
|
|
24568
24714
|
});
|
|
24569
24715
|
electron.ipcMain.handle(
|
|
24570
24716
|
Channels.AUTOFILL_ADD,
|
|
24571
|
-
(
|
|
24717
|
+
(event, profile) => {
|
|
24718
|
+
assertTrustedIpcSender(event);
|
|
24572
24719
|
return addProfile(sanitizeAutofillProfile(profile));
|
|
24573
24720
|
}
|
|
24574
24721
|
);
|
|
24575
|
-
electron.ipcMain.handle(Channels.AUTOFILL_UPDATE, (
|
|
24722
|
+
electron.ipcMain.handle(Channels.AUTOFILL_UPDATE, (event, id, updates) => {
|
|
24723
|
+
assertTrustedIpcSender(event);
|
|
24576
24724
|
assertString(id, "id");
|
|
24577
24725
|
return updateProfile(id, sanitizeAutofillUpdates(updates));
|
|
24578
24726
|
});
|
|
24579
|
-
electron.ipcMain.handle(Channels.AUTOFILL_DELETE, (
|
|
24727
|
+
electron.ipcMain.handle(Channels.AUTOFILL_DELETE, (event, id) => {
|
|
24728
|
+
assertTrustedIpcSender(event);
|
|
24580
24729
|
assertString(id, "id");
|
|
24581
24730
|
return deleteProfile(id);
|
|
24582
24731
|
});
|
|
24583
|
-
electron.ipcMain.handle(Channels.AUTOFILL_FILL, async (
|
|
24732
|
+
electron.ipcMain.handle(Channels.AUTOFILL_FILL, async (event, profileId) => {
|
|
24733
|
+
assertTrustedIpcSender(event);
|
|
24584
24734
|
assertString(profileId, "profileId");
|
|
24585
24735
|
const profile = getProfile(profileId);
|
|
24586
24736
|
if (!profile) throw new Error("Profile not found");
|
|
@@ -24650,12 +24800,14 @@ function registerPageDiffHandlers(windowState, sendToRendererViews) {
|
|
|
24650
24800
|
electron.ipcMain.on(Channels.PAGE_DIFF_ACTIVITY, (event) => {
|
|
24651
24801
|
const wc = event.sender;
|
|
24652
24802
|
if (!wc || wc.isDestroyed()) return;
|
|
24803
|
+
if (!isManagedTabIpcSender(event, windowState.tabManager)) return;
|
|
24653
24804
|
if (!allowPageEvent(wc.id)) return;
|
|
24654
24805
|
notePageMutationActivity(wc, sendToRendererViews);
|
|
24655
24806
|
});
|
|
24656
24807
|
electron.ipcMain.on(Channels.PAGE_DIFF_DIRTY, (event) => {
|
|
24657
24808
|
const wc = event.sender;
|
|
24658
24809
|
if (!wc || wc.isDestroyed()) return;
|
|
24810
|
+
if (!isManagedTabIpcSender(event, windowState.tabManager)) return;
|
|
24659
24811
|
if (!allowPageEvent(wc.id)) return;
|
|
24660
24812
|
schedulePageSnapshotCapture(wc, sendToRendererViews);
|
|
24661
24813
|
});
|
|
@@ -25802,19 +25954,22 @@ function getSafeBookmarkExportName(name) {
|
|
|
25802
25954
|
return safeName || "folder";
|
|
25803
25955
|
}
|
|
25804
25956
|
function registerBookmarkHandlers() {
|
|
25805
|
-
electron.ipcMain.handle(Channels.BOOKMARKS_GET, () => {
|
|
25957
|
+
electron.ipcMain.handle(Channels.BOOKMARKS_GET, (event) => {
|
|
25958
|
+
assertTrustedIpcSender(event);
|
|
25806
25959
|
return getState();
|
|
25807
25960
|
});
|
|
25808
25961
|
electron.ipcMain.handle(
|
|
25809
25962
|
Channels.FOLDER_CREATE,
|
|
25810
|
-
(
|
|
25963
|
+
(event, name, summary) => {
|
|
25964
|
+
assertTrustedIpcSender(event);
|
|
25811
25965
|
trackBookmarkAction("folder_create");
|
|
25812
25966
|
return createFolderWithSummary(name, summary);
|
|
25813
25967
|
}
|
|
25814
25968
|
);
|
|
25815
25969
|
electron.ipcMain.handle(
|
|
25816
25970
|
Channels.BOOKMARK_SAVE,
|
|
25817
|
-
(
|
|
25971
|
+
(event, url, title, folderId, note, intent, expectedContent, keyFields, agentHints) => {
|
|
25972
|
+
assertTrustedIpcSender(event);
|
|
25818
25973
|
trackBookmarkAction("save");
|
|
25819
25974
|
const result = saveBookmarkWithPolicy(url, title, folderId, note, {
|
|
25820
25975
|
onDuplicate: "update",
|
|
@@ -25835,12 +25990,14 @@ function registerBookmarkHandlers() {
|
|
|
25835
25990
|
);
|
|
25836
25991
|
electron.ipcMain.handle(
|
|
25837
25992
|
Channels.BOOKMARK_UPDATE,
|
|
25838
|
-
(
|
|
25993
|
+
(event, id, updates) => {
|
|
25994
|
+
assertTrustedIpcSender(event);
|
|
25839
25995
|
trackBookmarkAction("save");
|
|
25840
25996
|
return updateBookmark(id, updates);
|
|
25841
25997
|
}
|
|
25842
25998
|
);
|
|
25843
|
-
electron.ipcMain.handle(Channels.BOOKMARK_REMOVE, (
|
|
25999
|
+
electron.ipcMain.handle(Channels.BOOKMARK_REMOVE, (event, id) => {
|
|
26000
|
+
assertTrustedIpcSender(event);
|
|
25844
26001
|
trackBookmarkAction("remove");
|
|
25845
26002
|
return removeBookmark(id);
|
|
25846
26003
|
});
|
|
@@ -25933,22 +26090,26 @@ function registerBookmarkHandlers() {
|
|
|
25933
26090
|
trackBookmarkAction("import");
|
|
25934
26091
|
return importBookmarksFromJson(content);
|
|
25935
26092
|
});
|
|
25936
|
-
electron.ipcMain.handle(Channels.FOLDER_REMOVE, (
|
|
26093
|
+
electron.ipcMain.handle(Channels.FOLDER_REMOVE, (event, id, deleteContents) => {
|
|
26094
|
+
assertTrustedIpcSender(event);
|
|
25937
26095
|
trackBookmarkAction("folder_remove");
|
|
25938
26096
|
return removeFolder(id, deleteContents ?? false);
|
|
25939
26097
|
});
|
|
25940
26098
|
electron.ipcMain.handle(
|
|
25941
26099
|
Channels.FOLDER_RENAME,
|
|
25942
|
-
(
|
|
26100
|
+
(event, id, newName, summary) => {
|
|
26101
|
+
assertTrustedIpcSender(event);
|
|
25943
26102
|
return renameFolder(id, newName, summary);
|
|
25944
26103
|
}
|
|
25945
26104
|
);
|
|
25946
26105
|
}
|
|
25947
26106
|
function registerHistoryHandlers() {
|
|
25948
|
-
electron.ipcMain.handle(Channels.HISTORY_GET, () => {
|
|
26107
|
+
electron.ipcMain.handle(Channels.HISTORY_GET, (event) => {
|
|
26108
|
+
assertTrustedIpcSender(event);
|
|
25949
26109
|
return getState$1();
|
|
25950
26110
|
});
|
|
25951
|
-
electron.ipcMain.handle(Channels.HISTORY_SEARCH, (
|
|
26111
|
+
electron.ipcMain.handle(Channels.HISTORY_SEARCH, (event, query) => {
|
|
26112
|
+
assertTrustedIpcSender(event);
|
|
25952
26113
|
return search(query);
|
|
25953
26114
|
});
|
|
25954
26115
|
electron.ipcMain.handle(Channels.HISTORY_CLEAR, (event) => {
|
|
@@ -26073,10 +26234,12 @@ function registerPremiumHandlers(tabManager, sendToRendererViews) {
|
|
|
26073
26234
|
void handleUrl(currentUrl);
|
|
26074
26235
|
}
|
|
26075
26236
|
};
|
|
26076
|
-
electron.ipcMain.handle(Channels.PREMIUM_GET_STATE, () => {
|
|
26237
|
+
electron.ipcMain.handle(Channels.PREMIUM_GET_STATE, (event) => {
|
|
26238
|
+
assertTrustedIpcSender(event);
|
|
26077
26239
|
return getPremiumState();
|
|
26078
26240
|
});
|
|
26079
|
-
electron.ipcMain.handle(Channels.PREMIUM_ACTIVATION_START, async (
|
|
26241
|
+
electron.ipcMain.handle(Channels.PREMIUM_ACTIVATION_START, async (event, email) => {
|
|
26242
|
+
assertTrustedIpcSender(event);
|
|
26080
26243
|
assertString(email, "email");
|
|
26081
26244
|
if (!isValidEmail(email)) {
|
|
26082
26245
|
return errorResult("Invalid email format");
|
|
@@ -26090,7 +26253,8 @@ function registerPremiumHandlers(tabManager, sendToRendererViews) {
|
|
|
26090
26253
|
});
|
|
26091
26254
|
electron.ipcMain.handle(
|
|
26092
26255
|
Channels.PREMIUM_ACTIVATION_VERIFY,
|
|
26093
|
-
async (
|
|
26256
|
+
async (event, email, code, challengeToken) => {
|
|
26257
|
+
assertTrustedIpcSender(event);
|
|
26094
26258
|
assertString(email, "email");
|
|
26095
26259
|
assertString(code, "code");
|
|
26096
26260
|
assertString(challengeToken, "challengeToken");
|
|
@@ -26112,7 +26276,8 @@ function registerPremiumHandlers(tabManager, sendToRendererViews) {
|
|
|
26112
26276
|
return result;
|
|
26113
26277
|
}
|
|
26114
26278
|
);
|
|
26115
|
-
electron.ipcMain.handle(Channels.PREMIUM_CHECKOUT, async (
|
|
26279
|
+
electron.ipcMain.handle(Channels.PREMIUM_CHECKOUT, async (event, email) => {
|
|
26280
|
+
assertTrustedIpcSender(event);
|
|
26116
26281
|
trackPremiumFunnel("checkout_clicked");
|
|
26117
26282
|
const result = await getCheckoutUrl(email);
|
|
26118
26283
|
if (result.ok && result.url) {
|
|
@@ -26121,19 +26286,22 @@ function registerPremiumHandlers(tabManager, sendToRendererViews) {
|
|
|
26121
26286
|
}
|
|
26122
26287
|
return result;
|
|
26123
26288
|
});
|
|
26124
|
-
electron.ipcMain.handle(Channels.PREMIUM_RESET, () => {
|
|
26289
|
+
electron.ipcMain.handle(Channels.PREMIUM_RESET, (event) => {
|
|
26290
|
+
assertTrustedIpcSender(event);
|
|
26125
26291
|
trackPremiumFunnel("reset");
|
|
26126
26292
|
const state2 = resetPremium();
|
|
26127
26293
|
sendToRendererViews(Channels.PREMIUM_UPDATE, state2);
|
|
26128
26294
|
return state2;
|
|
26129
26295
|
});
|
|
26130
|
-
electron.ipcMain.handle(Channels.PREMIUM_TRACK_CONTEXT, (
|
|
26296
|
+
electron.ipcMain.handle(Channels.PREMIUM_TRACK_CONTEXT, (event, step) => {
|
|
26297
|
+
assertTrustedIpcSender(event);
|
|
26131
26298
|
assertString(step, "step");
|
|
26132
26299
|
if (PREMIUM_TRACKABLE_STEPS.includes(step)) {
|
|
26133
26300
|
trackPremiumFunnel(step);
|
|
26134
26301
|
}
|
|
26135
26302
|
});
|
|
26136
|
-
electron.ipcMain.handle(Channels.PREMIUM_PORTAL, async () => {
|
|
26303
|
+
electron.ipcMain.handle(Channels.PREMIUM_PORTAL, async (event) => {
|
|
26304
|
+
assertTrustedIpcSender(event);
|
|
26137
26305
|
trackPremiumFunnel("portal_opened");
|
|
26138
26306
|
const result = await getPortalUrl();
|
|
26139
26307
|
if (result.ok && result.url) {
|
|
@@ -26143,18 +26311,22 @@ function registerPremiumHandlers(tabManager, sendToRendererViews) {
|
|
|
26143
26311
|
});
|
|
26144
26312
|
}
|
|
26145
26313
|
function registerSessionHandlers(tabManager) {
|
|
26146
|
-
electron.ipcMain.handle(Channels.SESSION_LIST, () => {
|
|
26314
|
+
electron.ipcMain.handle(Channels.SESSION_LIST, (event) => {
|
|
26315
|
+
assertTrustedIpcSender(event);
|
|
26147
26316
|
return listNamedSessions();
|
|
26148
26317
|
});
|
|
26149
|
-
electron.ipcMain.handle(Channels.SESSION_SAVE, async (
|
|
26318
|
+
electron.ipcMain.handle(Channels.SESSION_SAVE, async (event, name) => {
|
|
26319
|
+
assertTrustedIpcSender(event);
|
|
26150
26320
|
assertString(name, "name");
|
|
26151
26321
|
return await saveNamedSession(tabManager, name);
|
|
26152
26322
|
});
|
|
26153
|
-
electron.ipcMain.handle(Channels.SESSION_LOAD, async (
|
|
26323
|
+
electron.ipcMain.handle(Channels.SESSION_LOAD, async (event, name) => {
|
|
26324
|
+
assertTrustedIpcSender(event);
|
|
26154
26325
|
assertString(name, "name");
|
|
26155
26326
|
return await loadNamedSession(tabManager, name);
|
|
26156
26327
|
});
|
|
26157
|
-
electron.ipcMain.handle(Channels.SESSION_DELETE, (
|
|
26328
|
+
electron.ipcMain.handle(Channels.SESSION_DELETE, (event, name) => {
|
|
26329
|
+
assertTrustedIpcSender(event);
|
|
26158
26330
|
assertString(name, "name");
|
|
26159
26331
|
return deleteNamedSession(name);
|
|
26160
26332
|
});
|
|
@@ -26312,6 +26484,10 @@ function snapshot() {
|
|
|
26312
26484
|
function emit() {
|
|
26313
26485
|
broadcaster?.(Channels.PERMISSIONS_GET, snapshot());
|
|
26314
26486
|
}
|
|
26487
|
+
function getDecision(origin, permission) {
|
|
26488
|
+
const existing = records.find((r) => r.origin === origin && r.permission === permission);
|
|
26489
|
+
return existing?.decision ?? sessionDecisions.get(key(origin, permission)) ?? null;
|
|
26490
|
+
}
|
|
26315
26491
|
function save(origin, permission, decision) {
|
|
26316
26492
|
const k = key(origin, permission);
|
|
26317
26493
|
const existing = records.find((r) => key(r.origin, r.permission) === k);
|
|
@@ -26344,6 +26520,12 @@ function setPermissionBroadcaster(fn) {
|
|
|
26344
26520
|
broadcaster = fn;
|
|
26345
26521
|
}
|
|
26346
26522
|
function installPermissionHandler() {
|
|
26523
|
+
electron.session.defaultSession.setPermissionCheckHandler((webContents, permission, requestingOrigin) => {
|
|
26524
|
+
if (!ALLOWED_PERMISSION_TYPES.has(permission)) return false;
|
|
26525
|
+
const origin = parseOrigin(requestingOrigin || webContents.getURL());
|
|
26526
|
+
if (!origin) return false;
|
|
26527
|
+
return getDecision(origin, permission) === "allow";
|
|
26528
|
+
});
|
|
26347
26529
|
electron.session.defaultSession.setPermissionRequestHandler((webContents, permission, callback, details) => {
|
|
26348
26530
|
if (!ALLOWED_PERMISSION_TYPES.has(permission)) {
|
|
26349
26531
|
callback(false);
|
|
@@ -26355,19 +26537,21 @@ function installPermissionHandler() {
|
|
|
26355
26537
|
return;
|
|
26356
26538
|
}
|
|
26357
26539
|
const k = key(origin, permission);
|
|
26358
|
-
const
|
|
26359
|
-
if (
|
|
26360
|
-
callback(
|
|
26361
|
-
return;
|
|
26362
|
-
}
|
|
26363
|
-
const sessionDecision = sessionDecisions.get(k);
|
|
26364
|
-
if (sessionDecision) {
|
|
26365
|
-
callback(sessionDecision === "allow");
|
|
26540
|
+
const decision = getDecision(origin, permission);
|
|
26541
|
+
if (decision) {
|
|
26542
|
+
callback(decision === "allow");
|
|
26366
26543
|
return;
|
|
26367
26544
|
}
|
|
26368
26545
|
const result = electron.dialog.showMessageBoxSync({
|
|
26369
26546
|
type: "question",
|
|
26370
|
-
buttons: [
|
|
26547
|
+
buttons: [
|
|
26548
|
+
"Deny Once",
|
|
26549
|
+
"Deny Until Quit",
|
|
26550
|
+
"Always Deny",
|
|
26551
|
+
"Allow Once",
|
|
26552
|
+
"Allow Until Quit",
|
|
26553
|
+
"Always Allow"
|
|
26554
|
+
],
|
|
26371
26555
|
defaultId: 0,
|
|
26372
26556
|
cancelId: 0,
|
|
26373
26557
|
title: "Site permission request",
|
|
@@ -26375,20 +26559,29 @@ function installPermissionHandler() {
|
|
|
26375
26559
|
detail: "Temporary choices are safer for camera, microphone, location, and clipboard access. Persistent choices can be cleared in Settings > Privacy."
|
|
26376
26560
|
});
|
|
26377
26561
|
if (result === 1) {
|
|
26378
|
-
|
|
26562
|
+
sessionDecisions.set(k, "deny");
|
|
26563
|
+
callback(false);
|
|
26379
26564
|
return;
|
|
26380
26565
|
}
|
|
26381
26566
|
if (result === 2) {
|
|
26567
|
+
save(origin, permission, "deny");
|
|
26568
|
+
callback(false);
|
|
26569
|
+
return;
|
|
26570
|
+
}
|
|
26571
|
+
if (result === 3) {
|
|
26572
|
+
callback(true);
|
|
26573
|
+
return;
|
|
26574
|
+
}
|
|
26575
|
+
if (result === 4) {
|
|
26382
26576
|
sessionDecisions.set(k, "allow");
|
|
26383
26577
|
callback(true);
|
|
26384
26578
|
return;
|
|
26385
26579
|
}
|
|
26386
|
-
if (result ===
|
|
26580
|
+
if (result === 5) {
|
|
26387
26581
|
save(origin, permission, "allow");
|
|
26388
26582
|
callback(true);
|
|
26389
26583
|
return;
|
|
26390
26584
|
}
|
|
26391
|
-
save(origin, permission, "deny");
|
|
26392
26585
|
callback(false);
|
|
26393
26586
|
});
|
|
26394
26587
|
}
|
|
@@ -26491,7 +26684,10 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26491
26684
|
requireTrusted(event);
|
|
26492
26685
|
createSecondaryWindow();
|
|
26493
26686
|
});
|
|
26494
|
-
electron.ipcMain.handle(Channels.IS_PRIVATE_MODE, () =>
|
|
26687
|
+
electron.ipcMain.handle(Channels.IS_PRIVATE_MODE, (event) => {
|
|
26688
|
+
requireTrusted(event);
|
|
26689
|
+
return false;
|
|
26690
|
+
});
|
|
26495
26691
|
let sidebarResizeRecoveryTimer = null;
|
|
26496
26692
|
let sidebarResizeActive = false;
|
|
26497
26693
|
let runtimeUpdateTimer = null;
|
|
@@ -26572,37 +26768,45 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26572
26768
|
onAIStreamIdle(() => {
|
|
26573
26769
|
sendToRendererViews(Channels.AI_STREAM_IDLE);
|
|
26574
26770
|
});
|
|
26575
|
-
electron.ipcMain.handle(Channels.TAB_CREATE, (
|
|
26771
|
+
electron.ipcMain.handle(Channels.TAB_CREATE, (event, url) => {
|
|
26772
|
+
requireTrusted(event);
|
|
26576
26773
|
const id = tabManager.createTab(url || loadSettings().defaultUrl);
|
|
26577
26774
|
layoutViews(windowState);
|
|
26578
26775
|
return id;
|
|
26579
26776
|
});
|
|
26580
|
-
electron.ipcMain.handle(Channels.TAB_CLOSE, (
|
|
26777
|
+
electron.ipcMain.handle(Channels.TAB_CLOSE, (event, id) => {
|
|
26778
|
+
requireTrusted(event);
|
|
26581
26779
|
tabManager.closeTab(id);
|
|
26582
26780
|
layoutViews(windowState);
|
|
26583
26781
|
});
|
|
26584
|
-
electron.ipcMain.handle(Channels.TAB_SWITCH, (
|
|
26782
|
+
electron.ipcMain.handle(Channels.TAB_SWITCH, (event, id) => {
|
|
26783
|
+
requireTrusted(event);
|
|
26585
26784
|
tabManager.switchTab(id);
|
|
26586
26785
|
layoutViews(windowState);
|
|
26587
26786
|
});
|
|
26588
26787
|
electron.ipcMain.handle(
|
|
26589
26788
|
Channels.TAB_NAVIGATE,
|
|
26590
|
-
(
|
|
26789
|
+
(event, id, url, postBody) => {
|
|
26790
|
+
requireTrusted(event);
|
|
26591
26791
|
assertString(id, "tabId");
|
|
26592
26792
|
assertString(url, "url");
|
|
26593
26793
|
return tabManager.navigateTab(id, url, postBody);
|
|
26594
26794
|
}
|
|
26595
26795
|
);
|
|
26596
|
-
electron.ipcMain.handle(Channels.TAB_BACK, (
|
|
26796
|
+
electron.ipcMain.handle(Channels.TAB_BACK, (event, id) => {
|
|
26797
|
+
requireTrusted(event);
|
|
26597
26798
|
tabManager.goBack(id);
|
|
26598
26799
|
});
|
|
26599
|
-
electron.ipcMain.handle(Channels.TAB_FORWARD, (
|
|
26800
|
+
electron.ipcMain.handle(Channels.TAB_FORWARD, (event, id) => {
|
|
26801
|
+
requireTrusted(event);
|
|
26600
26802
|
tabManager.goForward(id);
|
|
26601
26803
|
});
|
|
26602
|
-
electron.ipcMain.handle(Channels.TAB_RELOAD, (
|
|
26804
|
+
electron.ipcMain.handle(Channels.TAB_RELOAD, (event, id) => {
|
|
26805
|
+
requireTrusted(event);
|
|
26603
26806
|
tabManager.reloadTab(id);
|
|
26604
26807
|
});
|
|
26605
|
-
electron.ipcMain.handle(Channels.TAB_TOGGLE_AD_BLOCK, (
|
|
26808
|
+
electron.ipcMain.handle(Channels.TAB_TOGGLE_AD_BLOCK, (event, id) => {
|
|
26809
|
+
requireTrusted(event);
|
|
26606
26810
|
assertString(id, "id");
|
|
26607
26811
|
const tab = tabManager.getTab(id);
|
|
26608
26812
|
if (!tab) return null;
|
|
@@ -26610,87 +26814,108 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26610
26814
|
tab.setAdBlockingEnabled(newState);
|
|
26611
26815
|
return newState;
|
|
26612
26816
|
});
|
|
26613
|
-
electron.ipcMain.handle(Channels.TAB_ZOOM_IN, (
|
|
26817
|
+
electron.ipcMain.handle(Channels.TAB_ZOOM_IN, (event, id) => {
|
|
26818
|
+
requireTrusted(event);
|
|
26614
26819
|
assertString(id, "id");
|
|
26615
26820
|
tabManager.zoomIn(id);
|
|
26616
26821
|
});
|
|
26617
|
-
electron.ipcMain.handle(Channels.TAB_ZOOM_OUT, (
|
|
26822
|
+
electron.ipcMain.handle(Channels.TAB_ZOOM_OUT, (event, id) => {
|
|
26823
|
+
requireTrusted(event);
|
|
26618
26824
|
assertString(id, "id");
|
|
26619
26825
|
tabManager.zoomOut(id);
|
|
26620
26826
|
});
|
|
26621
|
-
electron.ipcMain.handle(Channels.TAB_ZOOM_RESET, (
|
|
26827
|
+
electron.ipcMain.handle(Channels.TAB_ZOOM_RESET, (event, id) => {
|
|
26828
|
+
requireTrusted(event);
|
|
26622
26829
|
assertString(id, "id");
|
|
26623
26830
|
tabManager.zoomReset(id);
|
|
26624
26831
|
});
|
|
26625
|
-
electron.ipcMain.handle(Channels.TAB_REOPEN_CLOSED, () => {
|
|
26832
|
+
electron.ipcMain.handle(Channels.TAB_REOPEN_CLOSED, (event) => {
|
|
26833
|
+
requireTrusted(event);
|
|
26626
26834
|
const id = tabManager.reopenClosedTab();
|
|
26627
26835
|
if (id) layoutViews(windowState);
|
|
26628
26836
|
return id;
|
|
26629
26837
|
});
|
|
26630
|
-
electron.ipcMain.handle(Channels.TAB_DUPLICATE, (
|
|
26838
|
+
electron.ipcMain.handle(Channels.TAB_DUPLICATE, (event, id) => {
|
|
26839
|
+
requireTrusted(event);
|
|
26631
26840
|
assertString(id, "id");
|
|
26632
26841
|
const newId = tabManager.duplicateTab(id);
|
|
26633
26842
|
if (newId) layoutViews(windowState);
|
|
26634
26843
|
return newId;
|
|
26635
26844
|
});
|
|
26636
|
-
electron.ipcMain.handle(Channels.TAB_PIN, (
|
|
26845
|
+
electron.ipcMain.handle(Channels.TAB_PIN, (event, id) => {
|
|
26846
|
+
requireTrusted(event);
|
|
26637
26847
|
assertString(id, "id");
|
|
26638
26848
|
tabManager.pinTab(id);
|
|
26639
26849
|
});
|
|
26640
|
-
electron.ipcMain.handle(Channels.TAB_UNPIN, (
|
|
26850
|
+
electron.ipcMain.handle(Channels.TAB_UNPIN, (event, id) => {
|
|
26851
|
+
requireTrusted(event);
|
|
26641
26852
|
assertString(id, "id");
|
|
26642
26853
|
tabManager.unpinTab(id);
|
|
26643
26854
|
});
|
|
26644
|
-
electron.ipcMain.handle(Channels.TAB_GROUP_CREATE, (
|
|
26855
|
+
electron.ipcMain.handle(Channels.TAB_GROUP_CREATE, (event, id) => {
|
|
26856
|
+
requireTrusted(event);
|
|
26645
26857
|
assertString(id, "id");
|
|
26646
26858
|
return tabManager.createGroupFromTab(id);
|
|
26647
26859
|
});
|
|
26648
|
-
electron.ipcMain.handle(Channels.TAB_GROUP_ADD_TAB, (
|
|
26860
|
+
electron.ipcMain.handle(Channels.TAB_GROUP_ADD_TAB, (event, id, groupId) => {
|
|
26861
|
+
requireTrusted(event);
|
|
26649
26862
|
assertString(id, "id");
|
|
26650
26863
|
assertString(groupId, "groupId");
|
|
26651
26864
|
tabManager.assignTabToGroup(id, groupId);
|
|
26652
26865
|
});
|
|
26653
|
-
electron.ipcMain.handle(Channels.TAB_GROUP_REMOVE_TAB, (
|
|
26866
|
+
electron.ipcMain.handle(Channels.TAB_GROUP_REMOVE_TAB, (event, id) => {
|
|
26867
|
+
requireTrusted(event);
|
|
26654
26868
|
assertString(id, "id");
|
|
26655
26869
|
tabManager.removeTabFromGroup(id);
|
|
26656
26870
|
});
|
|
26657
|
-
electron.ipcMain.handle(Channels.TAB_GROUP_TOGGLE_COLLAPSED, (
|
|
26871
|
+
electron.ipcMain.handle(Channels.TAB_GROUP_TOGGLE_COLLAPSED, (event, groupId) => {
|
|
26872
|
+
requireTrusted(event);
|
|
26658
26873
|
assertString(groupId, "groupId");
|
|
26659
26874
|
return tabManager.toggleGroupCollapsed(groupId);
|
|
26660
26875
|
});
|
|
26661
26876
|
electron.ipcMain.handle(
|
|
26662
26877
|
Channels.TAB_GROUP_SET_COLOR,
|
|
26663
|
-
(
|
|
26878
|
+
(event, groupId, color) => {
|
|
26879
|
+
requireTrusted(event);
|
|
26664
26880
|
assertString(groupId, "groupId");
|
|
26665
26881
|
assertString(color, "color");
|
|
26666
26882
|
tabManager.setGroupColor(groupId, color);
|
|
26667
26883
|
}
|
|
26668
26884
|
);
|
|
26669
|
-
electron.ipcMain.handle(Channels.TAB_TOGGLE_MUTE, (
|
|
26885
|
+
electron.ipcMain.handle(Channels.TAB_TOGGLE_MUTE, (event, id) => {
|
|
26886
|
+
requireTrusted(event);
|
|
26670
26887
|
assertString(id, "id");
|
|
26671
26888
|
return tabManager.toggleMuted(id);
|
|
26672
26889
|
});
|
|
26673
|
-
electron.ipcMain.handle(Channels.TAB_PRINT, (
|
|
26890
|
+
electron.ipcMain.handle(Channels.TAB_PRINT, (event, id) => {
|
|
26891
|
+
requireTrusted(event);
|
|
26674
26892
|
assertString(id, "id");
|
|
26675
26893
|
tabManager.printTab(id);
|
|
26676
26894
|
});
|
|
26677
|
-
electron.ipcMain.handle(Channels.TAB_PRINT_TO_PDF, (
|
|
26895
|
+
electron.ipcMain.handle(Channels.TAB_PRINT_TO_PDF, (event, id) => {
|
|
26896
|
+
requireTrusted(event);
|
|
26678
26897
|
assertString(id, "id");
|
|
26679
26898
|
return tabManager.saveTabAsPdf(id);
|
|
26680
26899
|
});
|
|
26681
|
-
electron.ipcMain.on(Channels.TAB_CONTEXT_MENU, (
|
|
26900
|
+
electron.ipcMain.on(Channels.TAB_CONTEXT_MENU, (event, id) => {
|
|
26901
|
+
requireTrusted(event);
|
|
26682
26902
|
assertString(id, "id");
|
|
26683
26903
|
showTabContextMenu(tabManager, id, mainWindow, () => layoutViews(windowState));
|
|
26684
26904
|
});
|
|
26685
|
-
electron.ipcMain.on(Channels.TAB_GROUP_CONTEXT_MENU, (
|
|
26905
|
+
electron.ipcMain.on(Channels.TAB_GROUP_CONTEXT_MENU, (event, groupId) => {
|
|
26906
|
+
requireTrusted(event);
|
|
26686
26907
|
assertString(groupId, "groupId");
|
|
26687
26908
|
showGroupContextMenu(tabManager, groupId, mainWindow);
|
|
26688
26909
|
});
|
|
26689
|
-
electron.ipcMain.handle(Channels.TAB_STATE_GET, () =>
|
|
26690
|
-
|
|
26691
|
-
|
|
26692
|
-
|
|
26693
|
-
|
|
26910
|
+
electron.ipcMain.handle(Channels.TAB_STATE_GET, (event) => {
|
|
26911
|
+
requireTrusted(event);
|
|
26912
|
+
return {
|
|
26913
|
+
tabs: tabManager.getAllStates(),
|
|
26914
|
+
activeId: tabManager.getActiveTabId() || ""
|
|
26915
|
+
};
|
|
26916
|
+
});
|
|
26917
|
+
electron.ipcMain.handle(Channels.AI_QUERY, async (event, query, history) => {
|
|
26918
|
+
requireTrusted(event);
|
|
26694
26919
|
const settings2 = loadSettings();
|
|
26695
26920
|
const chatConfig = settings2.chatProvider;
|
|
26696
26921
|
if (!chatConfig) {
|
|
@@ -26733,10 +26958,12 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26733
26958
|
})();
|
|
26734
26959
|
return { accepted: true };
|
|
26735
26960
|
});
|
|
26736
|
-
electron.ipcMain.handle(Channels.AI_CANCEL, () => {
|
|
26961
|
+
electron.ipcMain.handle(Channels.AI_CANCEL, (event) => {
|
|
26962
|
+
requireTrusted(event);
|
|
26737
26963
|
activeChatProvider?.cancel();
|
|
26738
26964
|
});
|
|
26739
|
-
electron.ipcMain.handle(Channels.AI_FETCH_MODELS, async (
|
|
26965
|
+
electron.ipcMain.handle(Channels.AI_FETCH_MODELS, async (event, config) => {
|
|
26966
|
+
requireTrusted(event);
|
|
26740
26967
|
try {
|
|
26741
26968
|
if (!config || typeof config !== "object" || !("id" in config)) {
|
|
26742
26969
|
return errorResult("Invalid provider configuration", { models: [] });
|
|
@@ -26748,12 +26975,14 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26748
26975
|
return errorResult(getErrorMessage(err), { models: [] });
|
|
26749
26976
|
}
|
|
26750
26977
|
});
|
|
26751
|
-
electron.ipcMain.handle(Channels.CONTENT_EXTRACT, async () => {
|
|
26978
|
+
electron.ipcMain.handle(Channels.CONTENT_EXTRACT, async (event) => {
|
|
26979
|
+
requireTrusted(event);
|
|
26752
26980
|
const activeTab = tabManager.getActiveTab();
|
|
26753
26981
|
if (!activeTab) return null;
|
|
26754
26982
|
return extractContent(activeTab.view.webContents);
|
|
26755
26983
|
});
|
|
26756
|
-
electron.ipcMain.handle(Channels.READER_MODE_TOGGLE, async () => {
|
|
26984
|
+
electron.ipcMain.handle(Channels.READER_MODE_TOGGLE, async (event) => {
|
|
26985
|
+
requireTrusted(event);
|
|
26757
26986
|
const activeTab = tabManager.getActiveTab();
|
|
26758
26987
|
if (!activeTab) return;
|
|
26759
26988
|
if (activeTab.state.isReaderMode) {
|
|
@@ -26773,7 +27002,8 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26773
27002
|
);
|
|
26774
27003
|
}
|
|
26775
27004
|
});
|
|
26776
|
-
electron.ipcMain.handle(Channels.SIDEBAR_TOGGLE, () => {
|
|
27005
|
+
electron.ipcMain.handle(Channels.SIDEBAR_TOGGLE, (event) => {
|
|
27006
|
+
requireTrusted(event);
|
|
26777
27007
|
windowState.uiState.sidebarOpen = !windowState.uiState.sidebarOpen;
|
|
26778
27008
|
layoutViews(windowState);
|
|
26779
27009
|
return {
|
|
@@ -26781,7 +27011,8 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26781
27011
|
width: windowState.uiState.sidebarWidth
|
|
26782
27012
|
};
|
|
26783
27013
|
});
|
|
26784
|
-
electron.ipcMain.handle(Channels.SIDEBAR_NAVIGATE, (
|
|
27014
|
+
electron.ipcMain.handle(Channels.SIDEBAR_NAVIGATE, (event, tab) => {
|
|
27015
|
+
requireTrusted(event);
|
|
26785
27016
|
assertString(tab, "tab");
|
|
26786
27017
|
if (!windowState.uiState.sidebarOpen) {
|
|
26787
27018
|
windowState.uiState.sidebarOpen = true;
|
|
@@ -26795,7 +27026,8 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26795
27026
|
width: windowState.uiState.sidebarWidth
|
|
26796
27027
|
};
|
|
26797
27028
|
});
|
|
26798
|
-
electron.ipcMain.handle(Channels.SIDEBAR_RESIZE_START, () => {
|
|
27029
|
+
electron.ipcMain.handle(Channels.SIDEBAR_RESIZE_START, (event) => {
|
|
27030
|
+
requireTrusted(event);
|
|
26799
27031
|
sidebarResizeActive = true;
|
|
26800
27032
|
clearSidebarResizeRecoveryTimer();
|
|
26801
27033
|
const [width, height] = windowState.mainWindow.getContentSize();
|
|
@@ -26810,14 +27042,16 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26810
27042
|
});
|
|
26811
27043
|
scheduleSidebarResizeRecovery();
|
|
26812
27044
|
});
|
|
26813
|
-
electron.ipcMain.handle(Channels.SIDEBAR_RESIZE, (
|
|
27045
|
+
electron.ipcMain.handle(Channels.SIDEBAR_RESIZE, (event, width) => {
|
|
27046
|
+
requireTrusted(event);
|
|
26814
27047
|
assertNumber(width, "width");
|
|
26815
27048
|
const clamped = Math.max(240, Math.min(800, Math.round(width)));
|
|
26816
27049
|
windowState.uiState.sidebarWidth = clamped;
|
|
26817
27050
|
resizeSidebarViews(windowState);
|
|
26818
27051
|
return clamped;
|
|
26819
27052
|
});
|
|
26820
|
-
electron.ipcMain.handle(Channels.SIDEBAR_RESIZE_COMMIT, () => {
|
|
27053
|
+
electron.ipcMain.handle(Channels.SIDEBAR_RESIZE_COMMIT, (event) => {
|
|
27054
|
+
requireTrusted(event);
|
|
26821
27055
|
sidebarResizeActive = false;
|
|
26822
27056
|
clearSidebarResizeRecoveryTimer();
|
|
26823
27057
|
setSetting("sidebarWidth", windowState.uiState.sidebarWidth);
|
|
@@ -26825,7 +27059,8 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26825
27059
|
});
|
|
26826
27060
|
electron.ipcMain.on(
|
|
26827
27061
|
Channels.RENDERER_VIEW_READY,
|
|
26828
|
-
(
|
|
27062
|
+
(event, view) => {
|
|
27063
|
+
requireTrusted(event);
|
|
26829
27064
|
if (view !== "sidebar") return;
|
|
26830
27065
|
if (!windowState.uiState.sidebarOpen) {
|
|
26831
27066
|
windowState.uiState.sidebarOpen = true;
|
|
@@ -26833,12 +27068,14 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26833
27068
|
}
|
|
26834
27069
|
}
|
|
26835
27070
|
);
|
|
26836
|
-
electron.ipcMain.handle(Channels.FOCUS_MODE_TOGGLE, () => {
|
|
27071
|
+
electron.ipcMain.handle(Channels.FOCUS_MODE_TOGGLE, (event) => {
|
|
27072
|
+
requireTrusted(event);
|
|
26837
27073
|
windowState.uiState.focusMode = !windowState.uiState.focusMode;
|
|
26838
27074
|
layoutViews(windowState);
|
|
26839
27075
|
return windowState.uiState.focusMode;
|
|
26840
27076
|
});
|
|
26841
|
-
electron.ipcMain.handle(Channels.SETTINGS_VISIBILITY, (
|
|
27077
|
+
electron.ipcMain.handle(Channels.SETTINGS_VISIBILITY, (event, open) => {
|
|
27078
|
+
requireTrusted(event);
|
|
26842
27079
|
windowState.uiState.settingsOpen = open;
|
|
26843
27080
|
if (open) {
|
|
26844
27081
|
windowState.uiState.sidebarOpen = false;
|
|
@@ -26846,10 +27083,14 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26846
27083
|
layoutViews(windowState);
|
|
26847
27084
|
return windowState.uiState.settingsOpen;
|
|
26848
27085
|
});
|
|
26849
|
-
electron.ipcMain.handle(Channels.SETTINGS_GET, () => {
|
|
27086
|
+
electron.ipcMain.handle(Channels.SETTINGS_GET, (event) => {
|
|
27087
|
+
requireTrusted(event);
|
|
26850
27088
|
return getRendererSettings();
|
|
26851
27089
|
});
|
|
26852
|
-
electron.ipcMain.handle(Channels.SETTINGS_HEALTH_GET, () =>
|
|
27090
|
+
electron.ipcMain.handle(Channels.SETTINGS_HEALTH_GET, (event) => {
|
|
27091
|
+
requireTrusted(event);
|
|
27092
|
+
return getRuntimeHealth();
|
|
27093
|
+
});
|
|
26853
27094
|
electron.ipcMain.handle(Channels.MCP_REGENERATE_TOKEN, (event) => {
|
|
26854
27095
|
requireTrusted(event);
|
|
26855
27096
|
return regenerateMcpAuthToken();
|
|
@@ -26874,7 +27115,10 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26874
27115
|
sendToRendererViews(Channels.SETTINGS_UPDATE, rendererSettings);
|
|
26875
27116
|
return rendererSettings;
|
|
26876
27117
|
});
|
|
26877
|
-
electron.ipcMain.handle(Channels.AGENT_RUNTIME_GET, () =>
|
|
27118
|
+
electron.ipcMain.handle(Channels.AGENT_RUNTIME_GET, (event) => {
|
|
27119
|
+
requireTrusted(event);
|
|
27120
|
+
return runtime2.getState();
|
|
27121
|
+
});
|
|
26878
27122
|
electron.ipcMain.handle(Channels.AGENT_PAUSE, (event) => {
|
|
26879
27123
|
requireTrusted(event);
|
|
26880
27124
|
return runtime2.pause();
|
|
@@ -26905,24 +27149,27 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26905
27149
|
);
|
|
26906
27150
|
electron.ipcMain.handle(
|
|
26907
27151
|
Channels.AGENT_CHECKPOINT_CREATE,
|
|
26908
|
-
(
|
|
26909
|
-
|
|
26910
|
-
|
|
26911
|
-
|
|
26912
|
-
(_, checkpointId) => runtime2.restoreCheckpoint(checkpointId)
|
|
26913
|
-
);
|
|
26914
|
-
electron.ipcMain.handle(
|
|
26915
|
-
Channels.AGENT_CHECKPOINT_UPDATE_NOTE,
|
|
26916
|
-
(_, checkpointId, note) => runtime2.updateCheckpointNote(checkpointId, note || "")
|
|
26917
|
-
);
|
|
26918
|
-
electron.ipcMain.handle(
|
|
26919
|
-
Channels.AGENT_UNDO_LAST_ACTION,
|
|
26920
|
-
() => runtime2.undoLastAction()
|
|
26921
|
-
);
|
|
26922
|
-
electron.ipcMain.handle(
|
|
26923
|
-
Channels.AGENT_SESSION_CAPTURE,
|
|
26924
|
-
(_, note) => runtime2.captureSession(note)
|
|
27152
|
+
(event, name, note) => {
|
|
27153
|
+
requireTrusted(event);
|
|
27154
|
+
return runtime2.createCheckpoint(name, note);
|
|
27155
|
+
}
|
|
26925
27156
|
);
|
|
27157
|
+
electron.ipcMain.handle(Channels.AGENT_CHECKPOINT_RESTORE, (event, checkpointId) => {
|
|
27158
|
+
requireTrusted(event);
|
|
27159
|
+
return runtime2.restoreCheckpoint(checkpointId);
|
|
27160
|
+
});
|
|
27161
|
+
electron.ipcMain.handle(Channels.AGENT_CHECKPOINT_UPDATE_NOTE, (event, checkpointId, note) => {
|
|
27162
|
+
requireTrusted(event);
|
|
27163
|
+
return runtime2.updateCheckpointNote(checkpointId, note || "");
|
|
27164
|
+
});
|
|
27165
|
+
electron.ipcMain.handle(Channels.AGENT_UNDO_LAST_ACTION, (event) => {
|
|
27166
|
+
requireTrusted(event);
|
|
27167
|
+
return runtime2.undoLastAction();
|
|
27168
|
+
});
|
|
27169
|
+
electron.ipcMain.handle(Channels.AGENT_SESSION_CAPTURE, (event, note) => {
|
|
27170
|
+
requireTrusted(event);
|
|
27171
|
+
return runtime2.captureSession(note);
|
|
27172
|
+
});
|
|
26926
27173
|
electron.ipcMain.handle(
|
|
26927
27174
|
Channels.AGENT_SESSION_RESTORE,
|
|
26928
27175
|
(event, snapshot2) => {
|
|
@@ -26931,7 +27178,8 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26931
27178
|
}
|
|
26932
27179
|
);
|
|
26933
27180
|
registerBookmarkHandlers();
|
|
26934
|
-
electron.ipcMain.handle(Channels.HIGHLIGHT_CAPTURE, async () => {
|
|
27181
|
+
electron.ipcMain.handle(Channels.HIGHLIGHT_CAPTURE, async (event) => {
|
|
27182
|
+
requireTrusted(event);
|
|
26935
27183
|
try {
|
|
26936
27184
|
const activeTab = tabManager.getActiveTab();
|
|
26937
27185
|
if (!activeTab) {
|
|
@@ -26975,10 +27223,12 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26975
27223
|
logger$4.warn("Failed to persist auto-highlight selection:", err);
|
|
26976
27224
|
}
|
|
26977
27225
|
});
|
|
26978
|
-
electron.ipcMain.handle(Channels.HIGHLIGHT_NAV_COUNT, () => {
|
|
27226
|
+
electron.ipcMain.handle(Channels.HIGHLIGHT_NAV_COUNT, (event) => {
|
|
27227
|
+
requireTrusted(event);
|
|
26979
27228
|
return getActiveHighlightCountSafe();
|
|
26980
27229
|
});
|
|
26981
|
-
electron.ipcMain.handle(Channels.HIGHLIGHT_NAV_SCROLL, (
|
|
27230
|
+
electron.ipcMain.handle(Channels.HIGHLIGHT_NAV_SCROLL, (event, index) => {
|
|
27231
|
+
requireTrusted(event);
|
|
26982
27232
|
const info = getActiveTabInfo(tabManager);
|
|
26983
27233
|
if (!info) return false;
|
|
26984
27234
|
try {
|
|
@@ -26988,7 +27238,8 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
26988
27238
|
return false;
|
|
26989
27239
|
}
|
|
26990
27240
|
});
|
|
26991
|
-
electron.ipcMain.handle(Channels.HIGHLIGHT_NAV_REMOVE, async (
|
|
27241
|
+
electron.ipcMain.handle(Channels.HIGHLIGHT_NAV_REMOVE, async (event, index) => {
|
|
27242
|
+
requireTrusted(event);
|
|
26992
27243
|
const info = getActiveTabInfo(tabManager);
|
|
26993
27244
|
if (!info) return false;
|
|
26994
27245
|
try {
|
|
@@ -27002,7 +27253,8 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
27002
27253
|
return false;
|
|
27003
27254
|
}
|
|
27004
27255
|
});
|
|
27005
|
-
electron.ipcMain.handle(Channels.HIGHLIGHT_NAV_CLEAR, async () => {
|
|
27256
|
+
electron.ipcMain.handle(Channels.HIGHLIGHT_NAV_CLEAR, async (event) => {
|
|
27257
|
+
requireTrusted(event);
|
|
27006
27258
|
const info = getActiveTabInfo(tabManager);
|
|
27007
27259
|
if (!info) return false;
|
|
27008
27260
|
try {
|
|
@@ -27017,22 +27269,27 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
27017
27269
|
}
|
|
27018
27270
|
});
|
|
27019
27271
|
const findBridge = createFindInPageBridge(tabManager, chromeView);
|
|
27020
|
-
electron.ipcMain.handle(Channels.FIND_IN_PAGE_START, (
|
|
27272
|
+
electron.ipcMain.handle(Channels.FIND_IN_PAGE_START, (event, text, options) => {
|
|
27273
|
+
requireTrusted(event);
|
|
27021
27274
|
return findBridge.start(text, options);
|
|
27022
27275
|
});
|
|
27023
|
-
electron.ipcMain.handle(Channels.FIND_IN_PAGE_NEXT, (
|
|
27276
|
+
electron.ipcMain.handle(Channels.FIND_IN_PAGE_NEXT, (event, forward) => {
|
|
27277
|
+
requireTrusted(event);
|
|
27024
27278
|
return findBridge.next(forward);
|
|
27025
27279
|
});
|
|
27026
|
-
electron.ipcMain.handle(Channels.FIND_IN_PAGE_STOP, (
|
|
27280
|
+
electron.ipcMain.handle(Channels.FIND_IN_PAGE_STOP, (event, action) => {
|
|
27281
|
+
requireTrusted(event);
|
|
27027
27282
|
findBridge.stop(action);
|
|
27028
27283
|
});
|
|
27029
27284
|
registerHistoryHandlers();
|
|
27030
|
-
electron.ipcMain.handle(Channels.DEVTOOLS_PANEL_TOGGLE, () => {
|
|
27285
|
+
electron.ipcMain.handle(Channels.DEVTOOLS_PANEL_TOGGLE, (event) => {
|
|
27286
|
+
requireTrusted(event);
|
|
27031
27287
|
windowState.uiState.devtoolsPanelOpen = !windowState.uiState.devtoolsPanelOpen;
|
|
27032
27288
|
layoutViews(windowState);
|
|
27033
27289
|
return { open: windowState.uiState.devtoolsPanelOpen };
|
|
27034
27290
|
});
|
|
27035
|
-
electron.ipcMain.handle(Channels.DEVTOOLS_PANEL_RESIZE, (
|
|
27291
|
+
electron.ipcMain.handle(Channels.DEVTOOLS_PANEL_RESIZE, (event, height) => {
|
|
27292
|
+
requireTrusted(event);
|
|
27036
27293
|
const clamped = Math.max(MIN_DEVTOOLS_PANEL, Math.min(MAX_DEVTOOLS_PANEL, Math.round(height)));
|
|
27037
27294
|
windowState.uiState.devtoolsPanelHeight = clamped;
|
|
27038
27295
|
layoutViews(windowState);
|
|
@@ -27045,7 +27302,8 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
27045
27302
|
registerHumanVaultHandlers();
|
|
27046
27303
|
registerWindowControlHandlers(mainWindow);
|
|
27047
27304
|
registerCodexHandlers();
|
|
27048
|
-
electron.ipcMain.handle(Channels.AUTOMATION_GET_INSTALLED, () => {
|
|
27305
|
+
electron.ipcMain.handle(Channels.AUTOMATION_GET_INSTALLED, (event) => {
|
|
27306
|
+
requireTrusted(event);
|
|
27049
27307
|
return getInstalledKits();
|
|
27050
27308
|
});
|
|
27051
27309
|
electron.ipcMain.handle(Channels.AUTOMATION_INSTALL_FROM_FILE, async (event) => {
|
|
@@ -27078,7 +27336,10 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
27078
27336
|
});
|
|
27079
27337
|
setDownloadBroadcaster(sendToRendererViews);
|
|
27080
27338
|
setPermissionBroadcaster(sendToRendererViews);
|
|
27081
|
-
electron.ipcMain.handle(Channels.DOWNLOADS_GET, () =>
|
|
27339
|
+
electron.ipcMain.handle(Channels.DOWNLOADS_GET, (event) => {
|
|
27340
|
+
requireTrusted(event);
|
|
27341
|
+
return listDownloads();
|
|
27342
|
+
});
|
|
27082
27343
|
electron.ipcMain.handle(Channels.DOWNLOADS_CLEAR, (event) => {
|
|
27083
27344
|
requireTrusted(event);
|
|
27084
27345
|
clearDownloads();
|
|
@@ -27092,7 +27353,10 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
27092
27353
|
requireTrusted(event);
|
|
27093
27354
|
return showDownloadInFolder(id);
|
|
27094
27355
|
});
|
|
27095
|
-
electron.ipcMain.handle(Channels.PERMISSIONS_GET, () =>
|
|
27356
|
+
electron.ipcMain.handle(Channels.PERMISSIONS_GET, (event) => {
|
|
27357
|
+
requireTrusted(event);
|
|
27358
|
+
return listPermissions();
|
|
27359
|
+
});
|
|
27096
27360
|
electron.ipcMain.handle(Channels.PERMISSIONS_CLEAR, (event) => {
|
|
27097
27361
|
requireTrusted(event);
|
|
27098
27362
|
clearPermissions();
|
|
@@ -27103,12 +27367,16 @@ function registerIpcHandlers(windowState, runtime2) {
|
|
|
27103
27367
|
clearPermissionsForOrigin(origin);
|
|
27104
27368
|
return true;
|
|
27105
27369
|
});
|
|
27106
|
-
electron.ipcMain.handle(Channels.UPDATES_CHECK, () =>
|
|
27370
|
+
electron.ipcMain.handle(Channels.UPDATES_CHECK, (event) => {
|
|
27371
|
+
requireTrusted(event);
|
|
27372
|
+
return checkForUpdates();
|
|
27373
|
+
});
|
|
27107
27374
|
electron.ipcMain.handle(Channels.UPDATES_OPEN_DOWNLOAD, (event) => {
|
|
27108
27375
|
requireTrusted(event);
|
|
27109
27376
|
return openUpdateDownload();
|
|
27110
27377
|
});
|
|
27111
|
-
electron.ipcMain.handle(Channels.TAB_TOGGLE_PIP, async () => {
|
|
27378
|
+
electron.ipcMain.handle(Channels.TAB_TOGGLE_PIP, async (event) => {
|
|
27379
|
+
requireTrusted(event);
|
|
27112
27380
|
return togglePictureInPicture(tabManager);
|
|
27113
27381
|
});
|
|
27114
27382
|
}
|