@xopcai/xopc 0.0.274 → 0.0.276
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/dist/browser-ext/_locales/en/messages.json +215 -0
- package/dist/browser-ext/_locales/zh_CN/messages.json +215 -0
- package/dist/browser-ext/dist/assets/{auth-O8RiOF3l.js → auth-ClQTK565.js} +97 -38
- package/dist/browser-ext/dist/assets/{sidepanel-C86O7q5Y.css → sidepanel-CeGqObOa.css} +41 -20
- package/dist/browser-ext/dist/background.js +36 -4
- package/dist/browser-ext/dist/sidepanel.html +2 -2
- package/dist/browser-ext/dist/sidepanel.js +416 -299
- package/dist/browser-ext/manifest.json +6 -4
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BckaANxj.js → agent-avatar-dicebear-sj_1IC5H.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-B8eyC6K1.js → agent-defaults-settings-panel-B5MRLEy8.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-CSWj_yo1.js → agents-CIzev0Qj.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DY-Zbgmt.js → app-management-settings-panel-DY3Vwxjq.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CoJR7ZRl.js → appearance-settings-BeXvF-dZ.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-Ch_9Ffgk.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BwAlRT53.js → archive-plugin-BSgaIIGE.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-R835uxgL.js → attachment-load-CGNt02hP.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BEZy0P_u.js → automations-page-DoafJiVA.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-MACr99IO.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CESFx3yb.js → binary-plugins-BsAL26Aq.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-DDJcf2wR.js → block-editor-BxB7m8aI.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automations-page-BH4lSfr5.js → browser-automations-page-BNsO-Ip2.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-Nvdoi0B1.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BluLJq5I.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-DYxxhcjb.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-D8U97O95.js → chat-terminal-dock-ZCFwco1W.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-Bpcp8UyE.js +2 -0
- package/dist/gateway/static/root/assets/{date-picker-7sDSMswL.js → date-picker-CpxFfgpg.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DMIC86ZW.js → dependency-picker-eCIGAfHa.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-BtdiY5jK.js → desktop-pet-_MSZvIDO.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-D_B8azDH.js → desktop-pet-settings-feBnJWkV.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-D_fB0fml.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-CoFKb01d.js → extension-debug-page-CotBlxJ-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CEkNsCAY.js → extension-page-CFBmQ7U3.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-Bi2R8P5j.js → extension-settings-page-Cd1lfh8z.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-BH35C8RI.js +1 -0
- package/dist/gateway/static/root/assets/{heartbeat-settings-DQtelFiU.js → heartbeat-settings-DRG0u1ON.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-BlZk-aD4.js +1 -0
- package/dist/gateway/static/root/assets/{index-SxqsTD4i.js → index-CfQor-TM.js} +34 -34
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BuYmZS1K.js → keyboard-shortcuts-settings-BLHsdFIQ.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-DJd71FlC.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-CExnZyGZ.js → local-apps-page-BjAj1xhq.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-CA5ArMoN.js → logs-page-5MWeZ6Ae.js} +2 -2
- package/dist/gateway/static/root/assets/{management-settings-1UiJPrkX.js → management-settings-CPHxDaOw.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-nNFOk9HL.js → media-plugins-BUOzcXCL.js} +1 -1
- package/dist/gateway/static/root/assets/note-detail-panel-Bch98ut3.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-CWO5dQKN.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-CRombigq.js → page-tabs-BgEYFhqS.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Bcuj43lk.js → preview-open-alternatives-C-pQIx6W.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-card-Cb3Xeoyx.js → proactive-card-DfjMVJUW.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-page-TbF9KVpm.js → proactive-page-BGVcVsbd.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DZFVirjV.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-B2g6inq-.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CbkUOkQY.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BudlvBu-.js → runtime-tools-settings-panel-DkAjFJ-9.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-Ch3MEX4h.js → schema-form-BpDcuSsl.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page--7-w-0WS.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BvZrH_sp.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CIA1AA-A.js → settings-form-section-RElRijJw.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-B0Khoduh.js → settings-page-CaixunoA.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Ul06Y5YX.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Cj9XWg-X.js → share-preview-page-CC-bFOTf.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DwV2Wh7S.js +1 -0
- package/dist/gateway/static/root/assets/{skill-reload-api-BM4Ezjbx.js → skill-reload-api-CcOtxf53.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-Dyh1kf9t.js → skills-page-DmRvRxtY.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DsQZkMti.js → skills-page.utils-CT0-daZD.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BSho_Tpk.js → system-settings-panel-DRIJ5mXq.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-BQjLHqSk.js +1 -0
- package/dist/gateway/static/root/assets/{tunnel-api-4DUHxSQG.js → tunnel-api-IvWcgZdD.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-BG8Yx7hj.js → use-autosave-Cq4--C1i.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-hwc5-nqV.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DYXwDhHq.js → voice-api-key-field-CbJ6tKGI.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CQqjzaRo.js → work-discovery-overlay-BG2pmXL3.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C5H-Fd-U.js → workflow-run-setup-panel-vw1229Fh.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DZWpJHDr.js +6 -0
- package/dist/gateway/static/root/index.html +1 -1
- package/dist/package.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +3 -0
- package/dist/src/agent/child-agent-factory.js +2 -1
- package/dist/src/agent/external-tools/endpoint-provider.js +1 -1
- package/dist/src/agent/tools/factory.d.ts +1 -0
- package/dist/src/agent/tools/factory.js +21 -4
- package/dist/src/agent/workflow/workflow-child-tools.js +2 -0
- package/dist/src/browser/providers/browser-ext-install.d.ts +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +86 -14
- package/dist/src/browser/providers/realtime-extension.d.ts +4 -1
- package/dist/src/browser/providers/realtime-extension.js +26 -10
- package/dist/src/browser/readiness.d.ts +4 -1
- package/dist/src/browser/readiness.js +11 -5
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +2 -2
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/gateway-workflow-host.types.d.ts +2 -0
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/browser.js +24 -11
- package/dist/src/gateway/hono/routes/endpoint-tools.js +9 -0
- package/dist/src/gateway/hono/routes/models.js +6 -0
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/providers/model-catalog-persistence.js +4 -0
- package/dist/src/providers/model-catalog-types.d.ts +1 -0
- package/dist/src/providers/xopc-cloud-model-source.js +12 -1
- package/dist/src/storage/sqlite/endpoint-session-binding-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/endpoint-session-binding-repository.js +9 -1
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.js +4 -1
- package/package.json +4 -4
- package/dist/gateway/static/root/assets/apps-page-CSMvkuot.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-CpaI13J7.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-CbTooPd2.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-C4LZWHhv.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-BAljmSa7.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CVRMjNNr.js +0 -2
- package/dist/gateway/static/root/assets/device-pairing-wizard-Dmh3Nh4d.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-q9p3sduo.js +0 -1
- package/dist/gateway/static/root/assets/home-page-COpGnTFZ.js +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-DV_17Zxc.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-panel-B5OQ0fBY.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-CVPPMVDl.js +0 -8
- package/dist/gateway/static/root/assets/project-detail-page-B9OQ2l9x.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DCqSTNkY.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-d9Fg70gX.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-D8RiQ-ag.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DVH_l6Hr.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-COJFl4N_.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-_OuE6A0G.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-B5HWM12k.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-IjVyv5jj.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-D1hMyPsY.js +0 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as RealtimeClient,
|
|
1
|
+
import { R as RealtimeClient, k as gatewayFetch, a as activeTabId, w as t, r as readBrowserOutbox, x as writeBrowserOutbox, g as deleteBrowserOutbox, f as currentTabDescriptor, T as TAB_BINDING_PREFIX, l as getAccessProfile, t as runWithTabSiteAccess, P as PENDING_CONTEXT_KEY, j as extensionLocale, d as captureTabWithPermission, p as pairGateway, v as setAutoConnectEnabled, n as readPendingBrowserPairing, o as readProfile, h as discoverLocalGateway, u as saveExtensionLocalePreference, s as revokeAndForgetProfile, c as cancelPendingBrowserPairing, m as loadExtensionLocalePreference } from './assets/auth-ClQTK565.js';
|
|
2
2
|
|
|
3
3
|
true &&(function polyfill() {
|
|
4
4
|
const relList = document.createElement("link").relList;
|
|
@@ -17364,14 +17364,14 @@ async function json(response) {
|
|
|
17364
17364
|
body = raw ? JSON.parse(raw) : {};
|
|
17365
17365
|
} catch {
|
|
17366
17366
|
throw new GatewayRequestError(
|
|
17367
|
-
response.ok ? "
|
|
17367
|
+
response.ok ? t("errorInvalidGatewayResponse") : t("errorGatewayStatus", String(response.status)),
|
|
17368
17368
|
response.status
|
|
17369
17369
|
);
|
|
17370
17370
|
}
|
|
17371
17371
|
if (!response.ok) {
|
|
17372
17372
|
const error = body.error;
|
|
17373
17373
|
throw new GatewayRequestError(
|
|
17374
|
-
typeof error === "string" ? error : error?.message ??
|
|
17374
|
+
typeof error === "string" ? error : error?.message ?? t("errorGatewayStatus", String(response.status)),
|
|
17375
17375
|
response.status
|
|
17376
17376
|
);
|
|
17377
17377
|
}
|
|
@@ -17398,7 +17398,7 @@ function mapMessage(value, index) {
|
|
|
17398
17398
|
if (!value2 || typeof value2 !== "object") return [];
|
|
17399
17399
|
const media = value2;
|
|
17400
17400
|
const mimeType = typeof media.mimeType === "string" ? media.mimeType : void 0;
|
|
17401
|
-
const name = typeof media.name === "string" && media.name.trim() ? media.name.trim() : "
|
|
17401
|
+
const name = typeof media.name === "string" && media.name.trim() ? media.name.trim() : t("attachment");
|
|
17402
17402
|
return [{
|
|
17403
17403
|
type: media.type === "image" || media.type === "photo" || mimeType?.startsWith("image/") ? "image" : "file",
|
|
17404
17404
|
name,
|
|
@@ -17459,12 +17459,14 @@ class BrowserChatClient {
|
|
|
17459
17459
|
recoveringOutbox = false;
|
|
17460
17460
|
lastOutboxRecoveryAt = 0;
|
|
17461
17461
|
sessionsRequest = 0;
|
|
17462
|
+
endpointBinding;
|
|
17463
|
+
endpointBindingTask;
|
|
17462
17464
|
endpointPoll;
|
|
17463
17465
|
onRuntimeMessage = (message) => {
|
|
17464
17466
|
if (message.type !== "browser/endpoint-ready" || !message.claim) return;
|
|
17465
17467
|
this.turnClaim = message.claim;
|
|
17466
17468
|
this.update({ endpointReady: true, error: void 0 });
|
|
17467
|
-
void this.recoverOutbox();
|
|
17469
|
+
void this.bindSessionEndpoint().then(() => this.recoverOutbox()).catch((cause) => this.update({ error: cause instanceof Error ? cause.message : String(cause) }));
|
|
17468
17470
|
};
|
|
17469
17471
|
snapshot = {
|
|
17470
17472
|
connection: "idle",
|
|
@@ -17557,6 +17559,8 @@ class BrowserChatClient {
|
|
|
17557
17559
|
this.realtime?.disconnect();
|
|
17558
17560
|
this.realtime = void 0;
|
|
17559
17561
|
this.turnClaim = void 0;
|
|
17562
|
+
this.endpointBinding = void 0;
|
|
17563
|
+
this.endpointBindingTask = void 0;
|
|
17560
17564
|
this.update({ endpointReady: false });
|
|
17561
17565
|
}
|
|
17562
17566
|
async reconnect() {
|
|
@@ -17567,18 +17571,55 @@ class BrowserChatClient {
|
|
|
17567
17571
|
ok: false,
|
|
17568
17572
|
error: cause instanceof Error ? cause.message : String(cause)
|
|
17569
17573
|
}));
|
|
17570
|
-
if (response?.ok === false) throw new Error(response.error ?? "
|
|
17574
|
+
if (response?.ok === false) throw new Error(response.error ?? t("errorReconnectEndpoint"));
|
|
17571
17575
|
await this.refreshEndpointClaim();
|
|
17572
17576
|
}
|
|
17573
17577
|
async refreshEndpointClaim() {
|
|
17578
|
+
const previousEndpointId = this.turnClaim?.endpointId;
|
|
17574
17579
|
const response = await chrome.runtime.sendMessage({ type: "browser/get-endpoint-claim" }).catch(() => void 0);
|
|
17575
17580
|
this.turnClaim = response?.claim;
|
|
17576
17581
|
this.update({
|
|
17577
17582
|
endpointReady: Boolean(this.turnClaim),
|
|
17578
17583
|
...response?.error ? { error: response.error } : this.turnClaim ? { error: void 0 } : {}
|
|
17579
17584
|
});
|
|
17585
|
+
if (this.turnClaim?.endpointId !== previousEndpointId) {
|
|
17586
|
+
this.endpointBinding = void 0;
|
|
17587
|
+
if (this.turnClaim) {
|
|
17588
|
+
void this.bindSessionEndpoint().catch((cause) => this.update({ error: cause instanceof Error ? cause.message : String(cause) }));
|
|
17589
|
+
}
|
|
17590
|
+
}
|
|
17580
17591
|
if (this.turnClaim && this.snapshot.pendingDelivery) void this.recoverOutbox();
|
|
17581
17592
|
}
|
|
17593
|
+
async bindSessionEndpoint() {
|
|
17594
|
+
const sessionKey = this.snapshot.sessionKey;
|
|
17595
|
+
const endpointId = this.turnClaim?.endpointId;
|
|
17596
|
+
if (!sessionKey || !endpointId) return;
|
|
17597
|
+
const desired = `${sessionKey}
|
|
17598
|
+
${endpointId}`;
|
|
17599
|
+
if (this.endpointBinding === desired) return;
|
|
17600
|
+
if (this.endpointBindingTask) {
|
|
17601
|
+
await this.endpointBindingTask;
|
|
17602
|
+
if (this.endpointBinding === desired) return;
|
|
17603
|
+
}
|
|
17604
|
+
const task = json(await gatewayFetch(
|
|
17605
|
+
`/api/endpoint-tools/bindings/${encodeURIComponent(sessionKey)}`,
|
|
17606
|
+
{
|
|
17607
|
+
method: "PUT",
|
|
17608
|
+
headers: { "Content-Type": "application/json" },
|
|
17609
|
+
body: JSON.stringify({ endpointId })
|
|
17610
|
+
}
|
|
17611
|
+
)).then(() => {
|
|
17612
|
+
if (this.snapshot.sessionKey === sessionKey && this.turnClaim?.endpointId === endpointId) {
|
|
17613
|
+
this.endpointBinding = desired;
|
|
17614
|
+
}
|
|
17615
|
+
});
|
|
17616
|
+
this.endpointBindingTask = task;
|
|
17617
|
+
try {
|
|
17618
|
+
await task;
|
|
17619
|
+
} finally {
|
|
17620
|
+
if (this.endpointBindingTask === task) this.endpointBindingTask = void 0;
|
|
17621
|
+
}
|
|
17622
|
+
}
|
|
17582
17623
|
async loadSessions(search) {
|
|
17583
17624
|
const requestId = ++this.sessionsRequest;
|
|
17584
17625
|
const params = new URLSearchParams({ channel: "webchat", limit: "30" });
|
|
@@ -17591,7 +17632,7 @@ class BrowserChatClient {
|
|
|
17591
17632
|
return [{
|
|
17592
17633
|
key: row.key,
|
|
17593
17634
|
...typeof row.sessionId === "string" ? { sessionId: row.sessionId } : {},
|
|
17594
|
-
title: [row.name, row.title, row.displayName].find((item) => typeof item === "string" && item.trim()) || "
|
|
17635
|
+
title: [row.name, row.title, row.displayName].find((item) => typeof item === "string" && item.trim()) || t("newChat"),
|
|
17595
17636
|
updatedAt: typeof row.updatedAt === "string" ? row.updatedAt : ""
|
|
17596
17637
|
}];
|
|
17597
17638
|
});
|
|
@@ -17637,6 +17678,8 @@ class BrowserChatClient {
|
|
|
17637
17678
|
this.reloadTabBinding()
|
|
17638
17679
|
]);
|
|
17639
17680
|
if (this.snapshot.sessionKey !== sessionKey) return;
|
|
17681
|
+
await this.bindSessionEndpoint();
|
|
17682
|
+
if (this.snapshot.sessionKey !== sessionKey) return;
|
|
17640
17683
|
const run = await json(await gatewayFetch(
|
|
17641
17684
|
`/api/sessions/${encodeURIComponent(sessionKey)}/run`
|
|
17642
17685
|
));
|
|
@@ -17659,11 +17702,12 @@ class BrowserChatClient {
|
|
|
17659
17702
|
async send(content, browserContexts = [], attachments = []) {
|
|
17660
17703
|
const text = content.trim();
|
|
17661
17704
|
if (!text && attachments.length === 0) return "sent";
|
|
17662
|
-
if (!this.snapshot.sessionKey) throw new Error("
|
|
17705
|
+
if (!this.snapshot.sessionKey) throw new Error(t("errorOpenChatBeforeSending"));
|
|
17663
17706
|
if (this.snapshot.submitting || this.snapshot.pendingDelivery || this.recoveringOutbox) {
|
|
17664
|
-
throw new Error("
|
|
17707
|
+
throw new Error(t("errorWaitQueuedMessage"));
|
|
17665
17708
|
}
|
|
17666
|
-
if (!this.turnClaim) throw new Error("
|
|
17709
|
+
if (!this.turnClaim) throw new Error(t("errorEndpointNotReady"));
|
|
17710
|
+
await this.bindSessionEndpoint();
|
|
17667
17711
|
const sessionKey = this.snapshot.sessionKey;
|
|
17668
17712
|
const clientMessageId = crypto.randomUUID();
|
|
17669
17713
|
const request = {
|
|
@@ -17720,7 +17764,7 @@ class BrowserChatClient {
|
|
|
17720
17764
|
if (this.snapshot.sessionKey === sessionKey) {
|
|
17721
17765
|
this.update({
|
|
17722
17766
|
pendingDelivery: false,
|
|
17723
|
-
error: "
|
|
17767
|
+
error: t("errorSentStatusUnknown")
|
|
17724
17768
|
});
|
|
17725
17769
|
}
|
|
17726
17770
|
return "sent";
|
|
@@ -17771,7 +17815,7 @@ class BrowserChatClient {
|
|
|
17771
17815
|
if (deliveryAccepted) {
|
|
17772
17816
|
this.update({
|
|
17773
17817
|
pendingDelivery: false,
|
|
17774
|
-
error: "
|
|
17818
|
+
error: t("errorSentStatusUnknown")
|
|
17775
17819
|
});
|
|
17776
17820
|
} else if (isRetryableDeliveryError(cause)) {
|
|
17777
17821
|
this.update({ pendingDelivery: true, error: void 0 });
|
|
@@ -17807,7 +17851,7 @@ class BrowserChatClient {
|
|
|
17807
17851
|
async updateModel(model) {
|
|
17808
17852
|
const sessionKey = this.snapshot.sessionKey;
|
|
17809
17853
|
const current = this.snapshot.modelConfig;
|
|
17810
|
-
if (!sessionKey || !current
|
|
17854
|
+
if (!sessionKey || !current) return;
|
|
17811
17855
|
const selected = this.snapshot.models.find((candidate) => candidate.id === model);
|
|
17812
17856
|
const thinkingLevel = selected?.thinking?.options?.includes(current.thinkingLevel) ? current.thinkingLevel : selected?.thinking?.default;
|
|
17813
17857
|
await this.patchModelConfig({ model, thinkingLevel });
|
|
@@ -17833,7 +17877,7 @@ class BrowserChatClient {
|
|
|
17833
17877
|
}
|
|
17834
17878
|
async bindActiveTab(mode) {
|
|
17835
17879
|
const sessionKey = this.snapshot.sessionKey;
|
|
17836
|
-
if (!sessionKey || !this.turnClaim) throw new Error("
|
|
17880
|
+
if (!sessionKey || !this.turnClaim) throw new Error(t("errorOpenChatForEndpoint"));
|
|
17837
17881
|
const descriptor = await currentTabDescriptor();
|
|
17838
17882
|
const result = await json(await gatewayFetch(
|
|
17839
17883
|
`/api/browser/tab-bindings/${encodeURIComponent(sessionKey)}`,
|
|
@@ -17970,7 +18014,7 @@ class BrowserChatClient {
|
|
|
17970
18014
|
));
|
|
17971
18015
|
const config = result.payload;
|
|
17972
18016
|
if (!config || typeof config.model !== "string" || typeof config.thinkingLevel !== "string") {
|
|
17973
|
-
throw new Error("
|
|
18017
|
+
throw new Error(t("errorInvalidModelConfig"));
|
|
17974
18018
|
}
|
|
17975
18019
|
if (this.snapshot.sessionKey !== sessionKey) return;
|
|
17976
18020
|
this.update({ modelConfig: {
|
|
@@ -17994,7 +18038,7 @@ class BrowserChatClient {
|
|
|
17994
18038
|
));
|
|
17995
18039
|
const config = result.payload;
|
|
17996
18040
|
if (!config || typeof config.model !== "string" || typeof config.thinkingLevel !== "string") {
|
|
17997
|
-
throw new Error("
|
|
18041
|
+
throw new Error(t("errorInvalidModelConfig"));
|
|
17998
18042
|
}
|
|
17999
18043
|
if (this.snapshot.sessionKey !== sessionKey) return;
|
|
18000
18044
|
this.update({ modelConfig: {
|
|
@@ -18067,7 +18111,7 @@ class BrowserChatClient {
|
|
|
18067
18111
|
}
|
|
18068
18112
|
requireProfileUrl() {
|
|
18069
18113
|
const profile = this.profileUrl;
|
|
18070
|
-
if (!profile) throw new Error("
|
|
18114
|
+
if (!profile) throw new Error(t("errorProfileNotLoaded"));
|
|
18071
18115
|
return profile;
|
|
18072
18116
|
}
|
|
18073
18117
|
profileUrl;
|
|
@@ -18101,14 +18145,14 @@ function encodeBase64(bytes) {
|
|
|
18101
18145
|
}
|
|
18102
18146
|
function assertSize(size) {
|
|
18103
18147
|
if (size > MAX_BROWSER_ATTACHMENT_BYTES) {
|
|
18104
|
-
throw new Error("
|
|
18148
|
+
throw new Error(t("errorAttachmentTooLarge"));
|
|
18105
18149
|
}
|
|
18106
18150
|
}
|
|
18107
18151
|
function assertSupportedFile(file) {
|
|
18108
18152
|
const mimeType = file.type.toLowerCase();
|
|
18109
18153
|
const name = file.name.toLowerCase();
|
|
18110
18154
|
if (mimeType.startsWith("image/") || SUPPORTED_DOCUMENT_MIME_TYPES.has(mimeType) || SUPPORTED_DOCUMENT_EXTENSIONS.some((extension) => name.endsWith(extension))) return;
|
|
18111
|
-
throw new Error("
|
|
18155
|
+
throw new Error(t("errorUnsupportedAttachment"));
|
|
18112
18156
|
}
|
|
18113
18157
|
async function fileToBrowserAttachment(file) {
|
|
18114
18158
|
assertSupportedFile(file);
|
|
@@ -18124,14 +18168,14 @@ async function fileToBrowserAttachment(file) {
|
|
|
18124
18168
|
}
|
|
18125
18169
|
async function captureVisibleScreenshot() {
|
|
18126
18170
|
const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
|
18127
|
-
if (activeTab.id === void 0) throw new Error("
|
|
18171
|
+
if (activeTab.id === void 0) throw new Error(t("errorNoActivePage"));
|
|
18128
18172
|
const dataUrl = await runWithTabSiteAccess(activeTab.id, async (accessibleTab) => {
|
|
18129
18173
|
const [currentTab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
|
18130
|
-
if (currentTab.id !== accessibleTab.id) throw new Error("
|
|
18174
|
+
if (currentTab.id !== accessibleTab.id) throw new Error(t("errorActiveTabChanged"));
|
|
18131
18175
|
return chrome.tabs.captureVisibleTab(accessibleTab.windowId, { format: "png" });
|
|
18132
18176
|
});
|
|
18133
18177
|
const separator = dataUrl.indexOf(",");
|
|
18134
|
-
if (separator < 0) throw new Error("
|
|
18178
|
+
if (separator < 0) throw new Error(t("errorInvalidScreenshot"));
|
|
18135
18179
|
const data = dataUrl.slice(separator + 1);
|
|
18136
18180
|
const size = Math.floor(data.length * 3 / 4);
|
|
18137
18181
|
assertSize(size);
|
|
@@ -18255,6 +18299,24 @@ function AlertIcon(props) {
|
|
|
18255
18299
|
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 8v5M12 16.5h.01" })
|
|
18256
18300
|
] });
|
|
18257
18301
|
}
|
|
18302
|
+
function SettingsIcon(props) {
|
|
18303
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(IconBase, { ...props, children: [
|
|
18304
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "3" }),
|
|
18305
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19.4 15a1.7 1.7 0 0 0 .34 1.88l.06.06-2.86 2.86-.06-.06A1.7 1.7 0 0 0 15 19.4a1.7 1.7 0 0 0-1 .6 1.7 1.7 0 0 0-.4 1.1V21H9.55v-.1A1.7 1.7 0 0 0 8.5 19.4a1.7 1.7 0 0 0-1.88.34l-.06.06-2.86-2.86.06-.06A1.7 1.7 0 0 0 4.1 15a1.7 1.7 0 0 0-.6-1 1.7 1.7 0 0 0-1.1-.4H2V9.55h.4A1.7 1.7 0 0 0 4.1 8.5a1.7 1.7 0 0 0-.34-1.88l-.06-.06L6.56 3.7l.06.06A1.7 1.7 0 0 0 8.5 4.1a1.7 1.7 0 0 0 1-.6 1.7 1.7 0 0 0 .4-1.1V2h4.05v.4A1.7 1.7 0 0 0 15 4.1a1.7 1.7 0 0 0 1.88-.34l.06-.06 2.86 2.86-.06.06A1.7 1.7 0 0 0 19.4 8.5a1.7 1.7 0 0 0 .6 1 1.7 1.7 0 0 0 1.1.4h.4v4.05h-.4A1.7 1.7 0 0 0 19.4 15Z" })
|
|
18306
|
+
] });
|
|
18307
|
+
}
|
|
18308
|
+
function SunIcon(props) {
|
|
18309
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(IconBase, { ...props, children: [
|
|
18310
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "4" }),
|
|
18311
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 2v2M12 20v2M4.93 4.93l1.42 1.42M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.42-1.42M17.66 6.34l1.41-1.41" })
|
|
18312
|
+
] });
|
|
18313
|
+
}
|
|
18314
|
+
function GlobeIcon(props) {
|
|
18315
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(IconBase, { ...props, children: [
|
|
18316
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "9" }),
|
|
18317
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M3 12h18M12 3a15 15 0 0 1 0 18M12 3a15 15 0 0 0 0 18" })
|
|
18318
|
+
] });
|
|
18319
|
+
}
|
|
18258
18320
|
|
|
18259
18321
|
/* eslint-disable no-bitwise */
|
|
18260
18322
|
|
|
@@ -26745,7 +26807,7 @@ function MarkdownContent({ children, streaming = false }) {
|
|
|
26745
26807
|
const html = reactExports.useMemo(() => renderSafeMarkdown(children), [children]);
|
|
26746
26808
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `markdown-content${streaming ? " is-streaming" : ""}`, children: [
|
|
26747
26809
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { dangerouslySetInnerHTML: { __html: html } }),
|
|
26748
|
-
streaming ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "streaming-caret", "aria-label": "
|
|
26810
|
+
streaming ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "streaming-caret", "aria-label": t("xopcResponding") }) : null
|
|
26749
26811
|
] });
|
|
26750
26812
|
}
|
|
26751
26813
|
|
|
@@ -26763,7 +26825,7 @@ const EMPTY = {
|
|
|
26763
26825
|
};
|
|
26764
26826
|
function formatMessageTime(timestamp) {
|
|
26765
26827
|
if (!timestamp) return "";
|
|
26766
|
-
return new Intl.DateTimeFormat(
|
|
26828
|
+
return new Intl.DateTimeFormat(extensionLocale(), { hour: "2-digit", minute: "2-digit" }).format(timestamp);
|
|
26767
26829
|
}
|
|
26768
26830
|
function formatSessionDate(timestamp) {
|
|
26769
26831
|
if (!timestamp) return "";
|
|
@@ -26771,7 +26833,28 @@ function formatSessionDate(timestamp) {
|
|
|
26771
26833
|
if (!Number.isFinite(date.getTime())) return "";
|
|
26772
26834
|
const now = /* @__PURE__ */ new Date();
|
|
26773
26835
|
if (date.toDateString() === now.toDateString()) return formatMessageTime(date.getTime());
|
|
26774
|
-
return new Intl.DateTimeFormat(
|
|
26836
|
+
return new Intl.DateTimeFormat(extensionLocale(), { month: "short", day: "numeric" }).format(date);
|
|
26837
|
+
}
|
|
26838
|
+
const RISK_MESSAGE_KEYS = {
|
|
26839
|
+
external_effect: "riskExternalEffect",
|
|
26840
|
+
destructive: "riskDestructive",
|
|
26841
|
+
sensitive: "riskSensitive",
|
|
26842
|
+
draft: "riskDraft",
|
|
26843
|
+
read: "riskRead"
|
|
26844
|
+
};
|
|
26845
|
+
const THINKING_MESSAGE_KEYS = {
|
|
26846
|
+
off: "thinkingOff",
|
|
26847
|
+
minimal: "thinkingMinimal",
|
|
26848
|
+
low: "thinkingLow",
|
|
26849
|
+
medium: "thinkingMedium",
|
|
26850
|
+
high: "thinkingHigh",
|
|
26851
|
+
xhigh: "thinkingXhigh",
|
|
26852
|
+
max: "thinkingMax",
|
|
26853
|
+
ultra: "thinkingUltra"
|
|
26854
|
+
};
|
|
26855
|
+
function thinkingLabel(level) {
|
|
26856
|
+
const key = THINKING_MESSAGE_KEYS[level];
|
|
26857
|
+
return key ? t(key) : level;
|
|
26775
26858
|
}
|
|
26776
26859
|
function formatFileSize(size) {
|
|
26777
26860
|
if (typeof size !== "number" || !Number.isFinite(size) || size < 0) return "";
|
|
@@ -26921,7 +27004,7 @@ function ChatPanel() {
|
|
|
26921
27004
|
setAtBottom(true);
|
|
26922
27005
|
try {
|
|
26923
27006
|
if (!snapshot.sessionKey) await client.createSession();
|
|
26924
|
-
if (pageContext?.stale) throw new Error("
|
|
27007
|
+
if (pageContext?.stale) throw new Error(t("errorAttachedPageChanged"));
|
|
26925
27008
|
await client.send(sending, pageContext ? [pageContext.context] : [], sendingAttachments);
|
|
26926
27009
|
setPageContext(void 0);
|
|
26927
27010
|
} catch (cause) {
|
|
@@ -26937,7 +27020,7 @@ function ChatPanel() {
|
|
|
26937
27020
|
setError("");
|
|
26938
27021
|
try {
|
|
26939
27022
|
const remaining = MAX_BROWSER_ATTACHMENTS - attachments.length;
|
|
26940
|
-
if (incoming.length > remaining) throw new Error(
|
|
27023
|
+
if (incoming.length > remaining) throw new Error(t("errorAttachmentLimit", String(MAX_BROWSER_ATTACHMENTS)));
|
|
26941
27024
|
const added = await Promise.all(incoming.map(fileToBrowserAttachment));
|
|
26942
27025
|
setAttachments((current) => [...current, ...added]);
|
|
26943
27026
|
} catch (cause) {
|
|
@@ -26950,7 +27033,7 @@ function ChatPanel() {
|
|
|
26950
27033
|
async function addScreenshot() {
|
|
26951
27034
|
setError("");
|
|
26952
27035
|
try {
|
|
26953
|
-
if (attachments.length >= MAX_BROWSER_ATTACHMENTS) throw new Error(
|
|
27036
|
+
if (attachments.length >= MAX_BROWSER_ATTACHMENTS) throw new Error(t("errorAttachmentLimit", String(MAX_BROWSER_ATTACHMENTS)));
|
|
26954
27037
|
const screenshot = await captureVisibleScreenshot();
|
|
26955
27038
|
setAttachments((current) => [...current, screenshot]);
|
|
26956
27039
|
} catch (cause) {
|
|
@@ -26971,7 +27054,7 @@ function ChatPanel() {
|
|
|
26971
27054
|
setError("");
|
|
26972
27055
|
try {
|
|
26973
27056
|
const tabId = await activeTabId();
|
|
26974
|
-
if (tabId === void 0) throw new Error("
|
|
27057
|
+
if (tabId === void 0) throw new Error(t("errorNoActivePage"));
|
|
26975
27058
|
setPageContext({
|
|
26976
27059
|
context: await captureTabWithPermission(tabId, mode),
|
|
26977
27060
|
tabId,
|
|
@@ -27069,13 +27152,13 @@ function ChatPanel() {
|
|
|
27069
27152
|
}
|
|
27070
27153
|
}
|
|
27071
27154
|
const activeSession = snapshot.sessions.find((session) => session.key === snapshot.sessionKey);
|
|
27072
|
-
const connectionText = snapshot.endpointReady ? "
|
|
27155
|
+
const connectionText = snapshot.endpointReady ? t("ready") : snapshot.connection === "connected" ? t("wakingUp") : snapshot.connection === "connecting" || snapshot.connection === "reconnecting" ? t("connecting") : t("offline");
|
|
27073
27156
|
const connectionProblem = !snapshot.endpointReady && (snapshot.connection === "error" || snapshot.connection === "disconnected");
|
|
27074
27157
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "chat", children: [
|
|
27075
27158
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "chat-toolbar", children: [
|
|
27076
27159
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { ref: sessionTrigger, className: "session-trigger", "aria-expanded": menuOpen, onClick: () => setMenuOpen((open) => !open), children: [
|
|
27077
27160
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "session-trigger-copy", children: [
|
|
27078
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "session-title", children: activeSession?.title ?? "
|
|
27161
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "session-title", children: activeSession?.title ?? t("newChat") }),
|
|
27079
27162
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "session-status", children: [
|
|
27080
27163
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `mini-status ${snapshot.endpointReady ? "online" : ""}` }),
|
|
27081
27164
|
connectionText
|
|
@@ -27083,16 +27166,16 @@ function ChatPanel() {
|
|
|
27083
27166
|
] }),
|
|
27084
27167
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDownIcon, { className: "icon-sm" })
|
|
27085
27168
|
] }),
|
|
27086
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "icon-button", type: "button", "aria-label": "
|
|
27169
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "icon-button", type: "button", "aria-label": t("startNewChat"), title: t("newChat"), disabled: snapshot.submitting, onClick: () => void runControlAction(() => client.createSession()), children: /* @__PURE__ */ jsxRuntimeExports.jsx(PlusIcon, {}) })
|
|
27087
27170
|
] }),
|
|
27088
27171
|
menuOpen ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-menu", ref: sessionMenu, children: [
|
|
27089
27172
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-menu-header", children: [
|
|
27090
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "
|
|
27091
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", "aria-label": "
|
|
27173
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: t("recentChats") }),
|
|
27174
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", "aria-label": t("closeRecentChats"), onClick: () => setMenuOpen(false), children: /* @__PURE__ */ jsxRuntimeExports.jsx(CloseIcon, {}) })
|
|
27092
27175
|
] }),
|
|
27093
27176
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "session-search", children: [
|
|
27094
27177
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SearchIcon, {}),
|
|
27095
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("input", { value: search, onChange: (event) => void runSearch(event.target.value), placeholder: "
|
|
27178
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("input", { value: search, onChange: (event) => void runSearch(event.target.value), placeholder: t("searchChats"), autoFocus: true })
|
|
27096
27179
|
] }),
|
|
27097
27180
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-list", children: [
|
|
27098
27181
|
snapshot.sessions.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { disabled: snapshot.submitting, className: session.key === snapshot.sessionKey ? "active" : "", onClick: () => {
|
|
@@ -27105,43 +27188,43 @@ function ChatPanel() {
|
|
|
27105
27188
|
] }),
|
|
27106
27189
|
session.key === snapshot.sessionKey ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckIcon, {}) : null
|
|
27107
27190
|
] }, session.key)),
|
|
27108
|
-
!snapshot.sessions.length ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "session-list-empty", children: "
|
|
27191
|
+
!snapshot.sessions.length ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "session-list-empty", children: t("noChatsFound") }) : null
|
|
27109
27192
|
] })
|
|
27110
27193
|
] }) : null,
|
|
27111
27194
|
connectionProblem ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "connection-banner", role: "alert", children: [
|
|
27112
27195
|
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertIcon, {}),
|
|
27113
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: snapshot.error || "
|
|
27114
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: () => void runControlAction(() => client.reconnect()), children: "
|
|
27196
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: snapshot.error || t("gatewayOffline") }),
|
|
27197
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: () => void runControlAction(() => client.reconnect()), children: t("reconnect") })
|
|
27115
27198
|
] }) : null,
|
|
27116
27199
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "messages-shell", children: [
|
|
27117
27200
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "messages", ref: viewport, onScroll: trackScrollPosition, children: [
|
|
27118
|
-
snapshot.sessionLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "message-skeleton", "aria-label": "
|
|
27201
|
+
snapshot.sessionLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "message-skeleton", "aria-label": t("loadingChat"), children: [
|
|
27119
27202
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
|
|
27120
27203
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", {}),
|
|
27121
27204
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", {})
|
|
27122
27205
|
] }) : null,
|
|
27123
27206
|
!snapshot.sessionLoading && !snapshot.messages.length && !snapshot.streamingText ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "empty-chat", children: [
|
|
27124
27207
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "empty-mark", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SparkleIcon, {}) }),
|
|
27125
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { children: "
|
|
27126
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "
|
|
27208
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { children: t("emptyChatTitle") }),
|
|
27209
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: t("emptyChatDescription") }),
|
|
27127
27210
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "quick-prompts", children: [
|
|
27128
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => void startQuickPrompt("
|
|
27211
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => void startQuickPrompt(t("promptSummarizePage"), "page"), children: [
|
|
27129
27212
|
/* @__PURE__ */ jsxRuntimeExports.jsx(PageIcon, {}),
|
|
27130
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "
|
|
27213
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("summarizePage") })
|
|
27131
27214
|
] }),
|
|
27132
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => void startQuickPrompt("
|
|
27215
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => void startQuickPrompt(t("promptExplainSelection"), "selection"), children: [
|
|
27133
27216
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectionIcon, {}),
|
|
27134
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "
|
|
27217
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("explainSelection") })
|
|
27135
27218
|
] }),
|
|
27136
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => void startQuickPrompt("
|
|
27219
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => void startQuickPrompt(t("promptHelpTask")), children: [
|
|
27137
27220
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CursorIcon, {}),
|
|
27138
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "
|
|
27221
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("helpWithTask") })
|
|
27139
27222
|
] })
|
|
27140
27223
|
] })
|
|
27141
27224
|
] }) : null,
|
|
27142
27225
|
snapshot.messages.map((message) => /* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: `message ${message.role}`, children: [
|
|
27143
27226
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "message-heading", children: [
|
|
27144
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "message-author", children: message.role === "user" ? "
|
|
27227
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "message-author", children: message.role === "user" ? t("you") : message.role === "assistant" ? "xopc" : t("system") }),
|
|
27145
27228
|
formatMessageTime(message.timestamp) ? /* @__PURE__ */ jsxRuntimeExports.jsx("time", { children: formatMessageTime(message.timestamp) }) : null
|
|
27146
27229
|
] }),
|
|
27147
27230
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "message-body", children: [
|
|
@@ -27149,7 +27232,7 @@ function ChatPanel() {
|
|
|
27149
27232
|
source.kind === "browser_page" ? /* @__PURE__ */ jsxRuntimeExports.jsx(PageIcon, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, {}),
|
|
27150
27233
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27151
27234
|
source.title,
|
|
27152
|
-
source.truncated ?
|
|
27235
|
+
source.truncated ? ` · ${t("truncated")}` : ""
|
|
27153
27236
|
] })
|
|
27154
27237
|
] }, `${source.title}-${index}`)) }) : null,
|
|
27155
27238
|
message.attachments?.length ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "message-attachments", children: message.attachments.map((attachment, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "message-attachment", title: attachment.mimeType, children: [
|
|
@@ -27161,20 +27244,20 @@ function ChatPanel() {
|
|
|
27161
27244
|
] }, `${attachment.name}-${index}`)) }) : null,
|
|
27162
27245
|
message.text ? message.role === "assistant" ? /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownContent, { children: message.text }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "plain-message-content", children: message.text }) : null
|
|
27163
27246
|
] }),
|
|
27164
|
-
message.role === "assistant" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "message-actions", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", "aria-label": "
|
|
27247
|
+
message.role === "assistant" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "message-actions", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", "aria-label": t("copyResponse"), title: t("copyResponse"), onClick: () => void copyMessage(message.id, message.text), children: [
|
|
27165
27248
|
copiedMessageId === message.id ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckIcon, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(CopyIcon, {}),
|
|
27166
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: copiedMessageId === message.id ? "
|
|
27249
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: copiedMessageId === message.id ? t("copied") : t("copy") })
|
|
27167
27250
|
] }) }) : null
|
|
27168
27251
|
] }, message.id)),
|
|
27169
27252
|
snapshot.streamingText ? /* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: "message assistant streaming", children: [
|
|
27170
27253
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "message-heading", children: [
|
|
27171
27254
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "message-author", children: "xopc" }),
|
|
27172
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "responding-label", children: "
|
|
27255
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "responding-label", children: t("responding") })
|
|
27173
27256
|
] }),
|
|
27174
27257
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "message-body", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownContent, { streaming: true, children: snapshot.streamingText }) })
|
|
27175
27258
|
] }) : null
|
|
27176
27259
|
] }),
|
|
27177
|
-
!atBottom ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "scroll-bottom-button", type: "button", "aria-label": "
|
|
27260
|
+
!atBottom ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "scroll-bottom-button", type: "button", "aria-label": t("scrollLatest"), title: t("scrollLatest"), onClick: () => scrollToBottom(true), children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowDownIcon, {}) }) : null
|
|
27178
27261
|
] }),
|
|
27179
27262
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
27180
27263
|
"form",
|
|
@@ -27203,26 +27286,27 @@ function ChatPanel() {
|
|
|
27203
27286
|
children: [
|
|
27204
27287
|
draggingFiles ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "file-drop-overlay", children: [
|
|
27205
27288
|
/* @__PURE__ */ jsxRuntimeExports.jsx(PaperclipIcon, {}),
|
|
27206
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "
|
|
27289
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("dropFiles") })
|
|
27207
27290
|
] }) : null,
|
|
27208
|
-
snapshot.browserApproval ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "request-card browser-approval", "aria-label": "
|
|
27291
|
+
snapshot.browserApproval ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "request-card browser-approval", "aria-label": t("browserApproval"), children: [
|
|
27209
27292
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "request-card-title", children: [
|
|
27210
27293
|
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertIcon, {}),
|
|
27211
27294
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [
|
|
27212
|
-
"
|
|
27213
|
-
|
|
27295
|
+
t("browserApproval"),
|
|
27296
|
+
" · ",
|
|
27297
|
+
t(RISK_MESSAGE_KEYS[snapshot.browserApproval.risk])
|
|
27214
27298
|
] })
|
|
27215
27299
|
] }),
|
|
27216
27300
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: snapshot.browserApproval.summary }),
|
|
27217
27301
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "request-actions", children: [
|
|
27218
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "request-primary", type: "button", onClick: () => void runControlAction(() => client.respondToBrowserApproval("approved")), children: "
|
|
27219
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: () => void runControlAction(() => client.respondToBrowserApproval("denied")), children: "
|
|
27302
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "request-primary", type: "button", onClick: () => void runControlAction(() => client.respondToBrowserApproval("approved")), children: t("allowOnce") }),
|
|
27303
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: () => void runControlAction(() => client.respondToBrowserApproval("denied")), children: t("deny") })
|
|
27220
27304
|
] })
|
|
27221
27305
|
] }) : null,
|
|
27222
|
-
snapshot.clarification ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "request-card", "aria-label": "
|
|
27306
|
+
snapshot.clarification ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "request-card", "aria-label": t("agentQuestion"), children: [
|
|
27223
27307
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "request-card-title", children: [
|
|
27224
27308
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SparkleIcon, {}),
|
|
27225
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: snapshot.clarification.kind === "approval" ? "
|
|
27309
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: snapshot.clarification.kind === "approval" ? t("approvalRequired") : t("xopcNeedsInput") })
|
|
27226
27310
|
] }),
|
|
27227
27311
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: snapshot.clarification.question }),
|
|
27228
27312
|
snapshot.clarification.choices?.length ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "choice-list", children: snapshot.clarification.choices.map((choice) => /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", disabled: clarificationSubmitting, onClick: () => void respondToClarification("answer", choice), children: choice }, choice)) }) : null,
|
|
@@ -27232,7 +27316,7 @@ function ChatPanel() {
|
|
|
27232
27316
|
{
|
|
27233
27317
|
value: clarificationAnswer,
|
|
27234
27318
|
onChange: (event) => setClarificationAnswer(event.target.value),
|
|
27235
|
-
placeholder: snapshot.clarification.suggestedAnswer ?? "
|
|
27319
|
+
placeholder: snapshot.clarification.suggestedAnswer ?? t("typeAnswer")
|
|
27236
27320
|
}
|
|
27237
27321
|
),
|
|
27238
27322
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -27241,16 +27325,16 @@ function ChatPanel() {
|
|
|
27241
27325
|
type: "button",
|
|
27242
27326
|
disabled: clarificationSubmitting || !clarificationAnswer.trim(),
|
|
27243
27327
|
onClick: () => void respondToClarification("answer", clarificationAnswer.trim()),
|
|
27244
|
-
children: "
|
|
27328
|
+
children: t("send")
|
|
27245
27329
|
}
|
|
27246
27330
|
)
|
|
27247
27331
|
] }),
|
|
27248
27332
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "clarification-actions", children: [
|
|
27249
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", disabled: clarificationSubmitting, onClick: () => void respondToClarification("agent_decide"), children: "
|
|
27250
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", disabled: clarificationSubmitting, onClick: () => void respondToClarification("cancel"), children: "
|
|
27333
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", disabled: clarificationSubmitting, onClick: () => void respondToClarification("agent_decide"), children: t("letXopcDecide") }),
|
|
27334
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", disabled: clarificationSubmitting, onClick: () => void respondToClarification("cancel"), children: t("cancelTask") })
|
|
27251
27335
|
] })
|
|
27252
27336
|
] }) : null,
|
|
27253
|
-
snapshot.pendingDelivery ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "composer-notice", role: "status", children: "
|
|
27337
|
+
snapshot.pendingDelivery ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "composer-notice", role: "status", children: t("queuedMessageNotice") }) : null,
|
|
27254
27338
|
error || !connectionProblem && snapshot.error ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "composer-error", role: "alert", children: [
|
|
27255
27339
|
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertIcon, {}),
|
|
27256
27340
|
error || snapshot.error
|
|
@@ -27259,23 +27343,23 @@ function ChatPanel() {
|
|
|
27259
27343
|
pageContext ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `context-chip${pageContext.stale ? " stale" : ""}`, children: [
|
|
27260
27344
|
pageContext.context.selection ? /* @__PURE__ */ jsxRuntimeExports.jsx(SelectionIcon, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(PageIcon, {}),
|
|
27261
27345
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27262
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: pageContext.source === "tab_mention" ? "
|
|
27346
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: pageContext.source === "tab_mention" ? t("tab") : pageContext.context.selection ? t("selection") : t("page") }),
|
|
27263
27347
|
" · ",
|
|
27264
27348
|
new URL(pageContext.context.url).hostname,
|
|
27265
27349
|
" · ",
|
|
27266
27350
|
pageContext.context.title
|
|
27267
27351
|
] }),
|
|
27268
|
-
pageContext.stale ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: () => void refreshPageContext(), children: "
|
|
27269
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "chip-remove", "aria-label": "
|
|
27352
|
+
pageContext.stale ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: () => void refreshPageContext(), children: t("refresh") }) : null,
|
|
27353
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "chip-remove", "aria-label": t("removePageContext"), onClick: () => setPageContext(void 0), children: /* @__PURE__ */ jsxRuntimeExports.jsx(CloseIcon, {}) })
|
|
27270
27354
|
] }) : null,
|
|
27271
27355
|
attachments.map((attachment, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "attachment-chip", children: [
|
|
27272
27356
|
attachment.type === "image" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CameraIcon, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, {}),
|
|
27273
27357
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27274
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: attachment.type === "image" ? "
|
|
27358
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: attachment.type === "image" ? t("image") : t("file") }),
|
|
27275
27359
|
" · ",
|
|
27276
27360
|
attachment.name
|
|
27277
27361
|
] }),
|
|
27278
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "chip-remove", "aria-label":
|
|
27362
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "chip-remove", "aria-label": t("removeAttachment", attachment.name), onClick: () => setAttachments((current) => current.filter((_, candidate) => candidate !== index)), children: /* @__PURE__ */ jsxRuntimeExports.jsx(CloseIcon, {}) })
|
|
27279
27363
|
] }, `${attachment.name}-${index}`))
|
|
27280
27364
|
] }) : null,
|
|
27281
27365
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -27289,7 +27373,7 @@ function ChatPanel() {
|
|
|
27289
27373
|
onChange: (event) => void addFiles(event.target.files)
|
|
27290
27374
|
}
|
|
27291
27375
|
),
|
|
27292
|
-
tabMention ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tab-mention-menu", role: "listbox", "aria-label": "
|
|
27376
|
+
tabMention ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tab-mention-menu", role: "listbox", "aria-label": t("openTabs"), children: mentionTabs.length ? mentionTabs.map((tab, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
27293
27377
|
"button",
|
|
27294
27378
|
{
|
|
27295
27379
|
type: "button",
|
|
@@ -27304,167 +27388,169 @@ function ChatPanel() {
|
|
|
27304
27388
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: tab.title }),
|
|
27305
27389
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("small", { children: [
|
|
27306
27390
|
tab.hostname,
|
|
27307
|
-
tab.active ?
|
|
27391
|
+
tab.active ? ` · ${t("currentTab")}` : ""
|
|
27308
27392
|
] })
|
|
27309
27393
|
]
|
|
27310
27394
|
},
|
|
27311
27395
|
tab.id
|
|
27312
|
-
)) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tab-mention-empty", children: "
|
|
27313
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
27314
|
-
|
|
27315
|
-
|
|
27316
|
-
|
|
27317
|
-
|
|
27318
|
-
|
|
27319
|
-
|
|
27320
|
-
|
|
27321
|
-
|
|
27322
|
-
|
|
27323
|
-
|
|
27324
|
-
|
|
27325
|
-
|
|
27326
|
-
|
|
27327
|
-
|
|
27328
|
-
|
|
27329
|
-
|
|
27330
|
-
|
|
27331
|
-
|
|
27332
|
-
|
|
27333
|
-
|
|
27334
|
-
|
|
27335
|
-
|
|
27336
|
-
|
|
27337
|
-
|
|
27338
|
-
|
|
27339
|
-
|
|
27340
|
-
|
|
27341
|
-
|
|
27342
|
-
|
|
27343
|
-
|
|
27344
|
-
|
|
27345
|
-
|
|
27346
|
-
|
|
27347
|
-
|
|
27348
|
-
|
|
27349
|
-
|
|
27350
|
-
|
|
27351
|
-
|
|
27352
|
-
}
|
|
27353
|
-
|
|
27354
|
-
|
|
27355
|
-
|
|
27356
|
-
|
|
27357
|
-
|
|
27358
|
-
|
|
27359
|
-
|
|
27360
|
-
|
|
27361
|
-
|
|
27362
|
-
|
|
27363
|
-
|
|
27364
|
-
|
|
27365
|
-
|
|
27366
|
-
|
|
27367
|
-
|
|
27368
|
-
|
|
27369
|
-
|
|
27396
|
+
)) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tab-mention-empty", children: t("noMatchingTabs") }) }) : null,
|
|
27397
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "composer-input-row", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
27398
|
+
"textarea",
|
|
27399
|
+
{
|
|
27400
|
+
ref: textarea,
|
|
27401
|
+
value: draft,
|
|
27402
|
+
onChange: (event) => {
|
|
27403
|
+
setDraft(event.target.value);
|
|
27404
|
+
void updateTabMention(event.target.value, event.target.selectionStart);
|
|
27405
|
+
},
|
|
27406
|
+
onSelect: (event) => void updateTabMention(event.currentTarget.value, event.currentTarget.selectionStart),
|
|
27407
|
+
onPaste: (event) => {
|
|
27408
|
+
if (!event.clipboardData.files.length) return;
|
|
27409
|
+
event.preventDefault();
|
|
27410
|
+
void addFiles(event.clipboardData.files);
|
|
27411
|
+
},
|
|
27412
|
+
onKeyDown: (event) => {
|
|
27413
|
+
if (tabMention) {
|
|
27414
|
+
if (event.key === "ArrowDown" && mentionTabs.length) {
|
|
27415
|
+
event.preventDefault();
|
|
27416
|
+
setMentionIndex((current) => (current + 1) % mentionTabs.length);
|
|
27417
|
+
return;
|
|
27418
|
+
}
|
|
27419
|
+
if (event.key === "ArrowUp" && mentionTabs.length) {
|
|
27420
|
+
event.preventDefault();
|
|
27421
|
+
setMentionIndex((current) => (current - 1 + mentionTabs.length) % mentionTabs.length);
|
|
27422
|
+
return;
|
|
27423
|
+
}
|
|
27424
|
+
if (event.key === "Escape") {
|
|
27425
|
+
event.preventDefault();
|
|
27426
|
+
mentionRequest.current += 1;
|
|
27427
|
+
setTabMention(void 0);
|
|
27428
|
+
setMentionTabs([]);
|
|
27429
|
+
return;
|
|
27430
|
+
}
|
|
27431
|
+
if (event.key === "Enter") {
|
|
27432
|
+
event.preventDefault();
|
|
27433
|
+
const selectedTab = mentionTabs[mentionIndex];
|
|
27434
|
+
if (selectedTab) void chooseMentionedTab(selectedTab);
|
|
27435
|
+
return;
|
|
27436
|
+
}
|
|
27437
|
+
}
|
|
27438
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
27439
|
+
event.preventDefault();
|
|
27440
|
+
event.currentTarget.form?.requestSubmit();
|
|
27441
|
+
}
|
|
27442
|
+
},
|
|
27443
|
+
onBlur: () => {
|
|
27444
|
+
mentionRequest.current += 1;
|
|
27445
|
+
setTabMention(void 0);
|
|
27446
|
+
setMentionTabs([]);
|
|
27447
|
+
},
|
|
27448
|
+
placeholder: t("composerPlaceholder"),
|
|
27449
|
+
disabled: snapshot.submitting,
|
|
27450
|
+
rows: 1
|
|
27451
|
+
}
|
|
27452
|
+
) }),
|
|
27453
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "composer-footer", children: [
|
|
27454
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "composer-toolbar-start", children: [
|
|
27455
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tools-anchor", children: [
|
|
27456
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { ref: toolsTrigger, type: "button", className: `composer-icon-button${toolsOpen ? " active" : ""}`, "aria-label": t("addContext"), "aria-expanded": toolsOpen, onClick: () => setToolsOpen((open) => !open), children: /* @__PURE__ */ jsxRuntimeExports.jsx(PlusIcon, {}) }),
|
|
27457
|
+
toolsOpen ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tools-menu", ref: toolsMenu, children: [
|
|
27458
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tools-menu-section", children: [
|
|
27459
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "tools-menu-label", children: t("addToMessage") }),
|
|
27460
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => {
|
|
27461
|
+
setToolsOpen(false);
|
|
27462
|
+
void attachPage("page");
|
|
27463
|
+
}, children: [
|
|
27464
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(PageIcon, {}),
|
|
27465
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27466
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: t("currentPage") }),
|
|
27467
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { children: t("sharePageContent") })
|
|
27468
|
+
] })
|
|
27469
|
+
] }),
|
|
27470
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => {
|
|
27471
|
+
setToolsOpen(false);
|
|
27472
|
+
void attachPage("selection");
|
|
27473
|
+
}, children: [
|
|
27474
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectionIcon, {}),
|
|
27475
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27476
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: t("selectedText") }),
|
|
27477
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { children: t("shareSelection") })
|
|
27478
|
+
] })
|
|
27370
27479
|
] }),
|
|
27371
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CloseIcon, {})
|
|
27372
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
27373
27480
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => {
|
|
27374
27481
|
setToolsOpen(false);
|
|
27375
|
-
void
|
|
27482
|
+
void addScreenshot();
|
|
27376
27483
|
}, children: [
|
|
27377
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
27484
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CameraIcon, {}),
|
|
27378
27485
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27379
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "
|
|
27380
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { children: "
|
|
27486
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: t("screenshot") }),
|
|
27487
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { children: t("captureVisibleTab") })
|
|
27381
27488
|
] })
|
|
27382
27489
|
] }),
|
|
27383
27490
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => {
|
|
27384
27491
|
setToolsOpen(false);
|
|
27385
|
-
|
|
27492
|
+
fileInput.current?.click();
|
|
27386
27493
|
}, children: [
|
|
27387
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
27494
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, {}),
|
|
27388
27495
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27389
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "
|
|
27390
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { children: "
|
|
27496
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: t("file") }),
|
|
27497
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { children: t("supportedFileTypes") })
|
|
27498
|
+
] })
|
|
27499
|
+
] })
|
|
27500
|
+
] }),
|
|
27501
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tools-menu-section tab-access-section", children: [
|
|
27502
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "tools-menu-label", children: t("liveTabAccess") }),
|
|
27503
|
+
snapshot.tabBinding ? /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "active-access", onClick: () => {
|
|
27504
|
+
setToolsOpen(false);
|
|
27505
|
+
void runControlAction(() => client.unbindActiveTab());
|
|
27506
|
+
}, children: [
|
|
27507
|
+
snapshot.tabBinding.mode === "act" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CursorIcon, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(EyeIcon, {}),
|
|
27508
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27509
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: snapshot.tabBinding.mode === "act" ? t("controlEnabled") : t("readEnabled") }),
|
|
27510
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { children: t("stopAccess") })
|
|
27511
|
+
] }),
|
|
27512
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CloseIcon, {})
|
|
27513
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
27514
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => {
|
|
27515
|
+
setToolsOpen(false);
|
|
27516
|
+
void runControlAction(() => client.bindActiveTab("read"));
|
|
27517
|
+
}, children: [
|
|
27518
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(EyeIcon, {}),
|
|
27519
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27520
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: t("readThisTab") }),
|
|
27521
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { children: t("keepPageAvailable") })
|
|
27522
|
+
] })
|
|
27523
|
+
] }),
|
|
27524
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => {
|
|
27525
|
+
setToolsOpen(false);
|
|
27526
|
+
void runControlAction(() => client.bindActiveTab("act"));
|
|
27527
|
+
}, children: [
|
|
27528
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CursorIcon, {}),
|
|
27529
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
27530
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: t("controlThisTab") }),
|
|
27531
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("small", { children: t("controlSafeguards") })
|
|
27532
|
+
] })
|
|
27391
27533
|
] })
|
|
27392
27534
|
] })
|
|
27393
27535
|
] })
|
|
27394
|
-
] })
|
|
27395
|
-
] })
|
|
27396
|
-
|
|
27397
|
-
|
|
27398
|
-
|
|
27399
|
-
|
|
27400
|
-
|
|
27401
|
-
|
|
27402
|
-
|
|
27403
|
-
|
|
27404
|
-
void updateTabMention(event.target.value, event.target.selectionStart);
|
|
27405
|
-
},
|
|
27406
|
-
onSelect: (event) => void updateTabMention(event.currentTarget.value, event.currentTarget.selectionStart),
|
|
27407
|
-
onPaste: (event) => {
|
|
27408
|
-
if (!event.clipboardData.files.length) return;
|
|
27409
|
-
event.preventDefault();
|
|
27410
|
-
void addFiles(event.clipboardData.files);
|
|
27411
|
-
},
|
|
27412
|
-
onKeyDown: (event) => {
|
|
27413
|
-
if (tabMention) {
|
|
27414
|
-
if (event.key === "ArrowDown" && mentionTabs.length) {
|
|
27415
|
-
event.preventDefault();
|
|
27416
|
-
setMentionIndex((current) => (current + 1) % mentionTabs.length);
|
|
27417
|
-
return;
|
|
27418
|
-
}
|
|
27419
|
-
if (event.key === "ArrowUp" && mentionTabs.length) {
|
|
27420
|
-
event.preventDefault();
|
|
27421
|
-
setMentionIndex((current) => (current - 1 + mentionTabs.length) % mentionTabs.length);
|
|
27422
|
-
return;
|
|
27423
|
-
}
|
|
27424
|
-
if (event.key === "Escape") {
|
|
27425
|
-
event.preventDefault();
|
|
27426
|
-
mentionRequest.current += 1;
|
|
27427
|
-
setTabMention(void 0);
|
|
27428
|
-
setMentionTabs([]);
|
|
27429
|
-
return;
|
|
27430
|
-
}
|
|
27431
|
-
if (event.key === "Enter") {
|
|
27432
|
-
event.preventDefault();
|
|
27433
|
-
const selectedTab = mentionTabs[mentionIndex];
|
|
27434
|
-
if (selectedTab) void chooseMentionedTab(selectedTab);
|
|
27435
|
-
return;
|
|
27436
|
-
}
|
|
27437
|
-
}
|
|
27438
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
27439
|
-
event.preventDefault();
|
|
27440
|
-
event.currentTarget.form?.requestSubmit();
|
|
27441
|
-
}
|
|
27442
|
-
},
|
|
27443
|
-
onBlur: () => {
|
|
27444
|
-
mentionRequest.current += 1;
|
|
27445
|
-
setTabMention(void 0);
|
|
27446
|
-
setMentionTabs([]);
|
|
27447
|
-
},
|
|
27448
|
-
placeholder: "Message xopc… Use @ to mention a tab",
|
|
27449
|
-
disabled: snapshot.submitting,
|
|
27450
|
-
rows: 1
|
|
27451
|
-
}
|
|
27452
|
-
),
|
|
27453
|
-
snapshot.runId ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "send-button stop-button", "aria-label": "Stop response", title: snapshot.stopping ? "Stopping response" : "Stop response", disabled: snapshot.stopping, onClick: () => void runControlAction(() => client.abort()), children: /* @__PURE__ */ jsxRuntimeExports.jsx(StopIcon, {}) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "send-button", type: "submit", "aria-label": "Send message", title: "Send message", disabled: snapshot.submitting || snapshot.pendingDelivery || snapshot.sessionLoading || !draft.trim() && attachments.length === 0 || !snapshot.endpointReady || Boolean(tabMention), children: /* @__PURE__ */ jsxRuntimeExports.jsx(SendIcon, {}) })
|
|
27454
|
-
] }),
|
|
27455
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "composer-footer", children: [
|
|
27456
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "composer-state", children: [
|
|
27457
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `mini-status ${snapshot.endpointReady ? "online" : ""}` }),
|
|
27458
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: snapshot.stopping ? "Stopping…" : snapshot.submitting ? "Sending…" : snapshot.pendingDelivery ? "Queued" : connectionText }),
|
|
27459
|
-
snapshot.tabBinding ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "access-pill", children: [
|
|
27460
|
-
snapshot.tabBinding.mode === "act" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CursorIcon, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(EyeIcon, {}),
|
|
27461
|
-
snapshot.tabBinding.mode === "act" ? "Control" : "Read"
|
|
27462
|
-
] }) : null
|
|
27536
|
+
] }) : null
|
|
27537
|
+
] }),
|
|
27538
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "composer-state", children: [
|
|
27539
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `mini-status ${snapshot.endpointReady ? "online" : ""}` }),
|
|
27540
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "composer-state-label", children: snapshot.stopping ? t("stopping") : snapshot.submitting ? t("sending") : snapshot.pendingDelivery ? t("queued") : connectionText }),
|
|
27541
|
+
snapshot.tabBinding ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "access-pill", children: [
|
|
27542
|
+
snapshot.tabBinding.mode === "act" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CursorIcon, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(EyeIcon, {}),
|
|
27543
|
+
snapshot.tabBinding.mode === "act" ? t("control") : t("read")
|
|
27544
|
+
] }) : null
|
|
27545
|
+
] })
|
|
27463
27546
|
] }),
|
|
27464
|
-
|
|
27465
|
-
|
|
27466
|
-
|
|
27467
|
-
|
|
27547
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "composer-toolbar-end", children: [
|
|
27548
|
+
snapshot.modelConfig ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "model-controls", children: [
|
|
27549
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("select", { "aria-label": t("model"), title: t("sessionModel"), value: snapshot.modelConfig.model, disabled: Boolean(snapshot.runId), onChange: (event) => void runControlAction(() => client.updateModel(event.target.value)), children: snapshot.models.map((model) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: model.id, children: model.name }, model.id)) }),
|
|
27550
|
+
thinkingOptions.length ? /* @__PURE__ */ jsxRuntimeExports.jsx("select", { "aria-label": t("thinkingLevel"), title: t("thinkingLevel"), value: snapshot.modelConfig.thinkingLevel, disabled: Boolean(snapshot.runId), onChange: (event) => void runControlAction(() => client.updateThinking(event.target.value)), children: thinkingOptions.map((level) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: level, children: thinkingLabel(level) }, level)) }) : null
|
|
27551
|
+
] }) : null,
|
|
27552
|
+
snapshot.runId ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "send-button stop-button", "aria-label": t("stopResponse"), title: snapshot.stopping ? t("stoppingResponse") : t("stopResponse"), disabled: snapshot.stopping, onClick: () => void runControlAction(() => client.abort()), children: /* @__PURE__ */ jsxRuntimeExports.jsx(StopIcon, {}) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "send-button", type: "submit", "aria-label": t("sendMessage"), title: t("sendMessage"), disabled: snapshot.submitting || snapshot.pendingDelivery || snapshot.sessionLoading || !draft.trim() && attachments.length === 0 || !snapshot.endpointReady || Boolean(tabMention), children: /* @__PURE__ */ jsxRuntimeExports.jsx(SendIcon, {}) })
|
|
27553
|
+
] })
|
|
27468
27554
|
] })
|
|
27469
27555
|
]
|
|
27470
27556
|
}
|
|
@@ -27472,6 +27558,7 @@ function ChatPanel() {
|
|
|
27472
27558
|
] });
|
|
27473
27559
|
}
|
|
27474
27560
|
|
|
27561
|
+
const THEME_STORAGE_KEY = "xopc.sidepanel.theme";
|
|
27475
27562
|
function isSidePanelTheme(value) {
|
|
27476
27563
|
return value === "light" || value === "dark";
|
|
27477
27564
|
}
|
|
@@ -27479,66 +27566,15 @@ function applySidePanelTheme(theme) {
|
|
|
27479
27566
|
document.documentElement.dataset.theme = theme;
|
|
27480
27567
|
document.documentElement.style.colorScheme = theme;
|
|
27481
27568
|
}
|
|
27482
|
-
function
|
|
27483
|
-
|
|
27569
|
+
async function loadSidePanelThemePreference() {
|
|
27570
|
+
const stored = await chrome.storage.local.get(THEME_STORAGE_KEY);
|
|
27571
|
+
const theme = isSidePanelTheme(stored[THEME_STORAGE_KEY]) ? stored[THEME_STORAGE_KEY] : globalThis.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
27572
|
+
applySidePanelTheme(theme);
|
|
27573
|
+
return theme;
|
|
27484
27574
|
}
|
|
27485
|
-
function
|
|
27486
|
-
|
|
27487
|
-
|
|
27488
|
-
if (url.protocol === "http:" && (url.hostname === "127.0.0.1" || url.hostname === "localhost")) {
|
|
27489
|
-
return true;
|
|
27490
|
-
}
|
|
27491
|
-
return Boolean(gatewayUrl && url.origin === new URL(gatewayUrl).origin);
|
|
27492
|
-
} catch {
|
|
27493
|
-
return false;
|
|
27494
|
-
}
|
|
27495
|
-
}
|
|
27496
|
-
async function pageTheme(tabId) {
|
|
27497
|
-
try {
|
|
27498
|
-
const [{ result } = {}] = await chrome.scripting.executeScript({
|
|
27499
|
-
target: { tabId },
|
|
27500
|
-
func: () => ({
|
|
27501
|
-
theme: document.documentElement.dataset.theme
|
|
27502
|
-
})
|
|
27503
|
-
});
|
|
27504
|
-
return isSidePanelTheme(result?.theme) ? result.theme : void 0;
|
|
27505
|
-
} catch {
|
|
27506
|
-
return void 0;
|
|
27507
|
-
}
|
|
27508
|
-
}
|
|
27509
|
-
async function syncSidePanelTheme(gatewayUrl) {
|
|
27510
|
-
const tabs = (await chrome.tabs.query({})).filter((tab) => {
|
|
27511
|
-
return typeof tab.id === "number" && Boolean(tab.url) && isGatewayThemePageUrl(tab.url, gatewayUrl);
|
|
27512
|
-
}).sort((left, right) => Number(right.active) - Number(left.active));
|
|
27513
|
-
for (const tab of tabs) {
|
|
27514
|
-
const theme = await pageTheme(tab.id);
|
|
27515
|
-
if (theme) {
|
|
27516
|
-
applySidePanelTheme(theme);
|
|
27517
|
-
return;
|
|
27518
|
-
}
|
|
27519
|
-
}
|
|
27520
|
-
}
|
|
27521
|
-
function watchSidePanelTheme(gatewayUrl) {
|
|
27522
|
-
const sync = () => {
|
|
27523
|
-
void syncSidePanelTheme(gatewayUrl);
|
|
27524
|
-
};
|
|
27525
|
-
const onUpdated = (_tabId, change) => {
|
|
27526
|
-
if (change.status === "complete" || change.url) sync();
|
|
27527
|
-
};
|
|
27528
|
-
const onVisibilityChange = () => {
|
|
27529
|
-
if (document.visibilityState === "visible") sync();
|
|
27530
|
-
};
|
|
27531
|
-
sync();
|
|
27532
|
-
window.addEventListener("focus", sync);
|
|
27533
|
-
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
27534
|
-
chrome.tabs.onActivated.addListener(sync);
|
|
27535
|
-
chrome.tabs.onUpdated.addListener(onUpdated);
|
|
27536
|
-
return () => {
|
|
27537
|
-
window.removeEventListener("focus", sync);
|
|
27538
|
-
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
27539
|
-
chrome.tabs.onActivated.removeListener(sync);
|
|
27540
|
-
chrome.tabs.onUpdated.removeListener(onUpdated);
|
|
27541
|
-
};
|
|
27575
|
+
async function saveSidePanelThemePreference(theme) {
|
|
27576
|
+
await chrome.storage.local.set({ [THEME_STORAGE_KEY]: theme });
|
|
27577
|
+
applySidePanelTheme(theme);
|
|
27542
27578
|
}
|
|
27543
27579
|
|
|
27544
27580
|
async function reconnectBrowserBridge() {
|
|
@@ -27547,23 +27583,23 @@ async function reconnectBrowserBridge() {
|
|
|
27547
27583
|
function pairingErrorMessage(cause) {
|
|
27548
27584
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
27549
27585
|
if (message === "Gateway site permission was not granted") {
|
|
27550
|
-
return "
|
|
27586
|
+
return t("errorGatewayPermissionHelp");
|
|
27551
27587
|
}
|
|
27552
27588
|
if (message === "PAIRING_EXPIRED" || message === "Pairing expired" || message === "Pairing invitation has expired") {
|
|
27553
|
-
return "
|
|
27589
|
+
return t("errorInvitationExpiredHelp");
|
|
27554
27590
|
}
|
|
27555
27591
|
if (message === "PAIRING_DEVICE_MISMATCH") {
|
|
27556
|
-
return "
|
|
27592
|
+
return t("errorPairingDeviceMismatch");
|
|
27557
27593
|
}
|
|
27558
27594
|
if (message === "No Gateway route could be reached") {
|
|
27559
|
-
return "
|
|
27595
|
+
return t("errorNoReachableGatewayRouteHelp");
|
|
27560
27596
|
}
|
|
27561
27597
|
if (message.startsWith("PAIRING_ROUTE_PERMISSION_REQUIRED:")) {
|
|
27562
|
-
return "
|
|
27598
|
+
return t("errorNextRoutePermission");
|
|
27563
27599
|
}
|
|
27564
27600
|
return message;
|
|
27565
27601
|
}
|
|
27566
|
-
function SidePanelApp() {
|
|
27602
|
+
function SidePanelApp({ initialLocale, initialTheme }) {
|
|
27567
27603
|
const [profile, setProfile] = reactExports.useState();
|
|
27568
27604
|
const [invitation, setInvitation] = reactExports.useState("");
|
|
27569
27605
|
const [confirmationCode, setConfirmationCode] = reactExports.useState("");
|
|
@@ -27571,8 +27607,13 @@ function SidePanelApp() {
|
|
|
27571
27607
|
const [error, setError] = reactExports.useState("");
|
|
27572
27608
|
const [localInvitation, setLocalInvitation] = reactExports.useState("");
|
|
27573
27609
|
const [nextOrigin, setNextOrigin] = reactExports.useState();
|
|
27610
|
+
const [locale, setLocale] = reactExports.useState(initialLocale);
|
|
27611
|
+
const [theme, setTheme] = reactExports.useState(initialTheme);
|
|
27612
|
+
const [settingsOpen, setSettingsOpen] = reactExports.useState(false);
|
|
27574
27613
|
const initializationStarted = reactExports.useRef(false);
|
|
27575
27614
|
const pairingStarted = reactExports.useRef(false);
|
|
27615
|
+
const settingsMenu = reactExports.useRef(null);
|
|
27616
|
+
const settingsTrigger = reactExports.useRef(null);
|
|
27576
27617
|
const connect = reactExports.useCallback(async (value, origin) => {
|
|
27577
27618
|
if (pairingStarted.current) return;
|
|
27578
27619
|
pairingStarted.current = true;
|
|
@@ -27622,7 +27663,31 @@ function SidePanelApp() {
|
|
|
27622
27663
|
await connect(local.invitation);
|
|
27623
27664
|
})();
|
|
27624
27665
|
}, [connect]);
|
|
27625
|
-
reactExports.useEffect(() =>
|
|
27666
|
+
reactExports.useEffect(() => {
|
|
27667
|
+
function closeSettings(event) {
|
|
27668
|
+
const target = event.target;
|
|
27669
|
+
if (!settingsMenu.current?.contains(target) && !settingsTrigger.current?.contains(target)) {
|
|
27670
|
+
setSettingsOpen(false);
|
|
27671
|
+
}
|
|
27672
|
+
}
|
|
27673
|
+
function closeOnEscape(event) {
|
|
27674
|
+
if (event.key === "Escape") setSettingsOpen(false);
|
|
27675
|
+
}
|
|
27676
|
+
document.addEventListener("mousedown", closeSettings);
|
|
27677
|
+
document.addEventListener("keydown", closeOnEscape);
|
|
27678
|
+
return () => {
|
|
27679
|
+
document.removeEventListener("mousedown", closeSettings);
|
|
27680
|
+
document.removeEventListener("keydown", closeOnEscape);
|
|
27681
|
+
};
|
|
27682
|
+
}, []);
|
|
27683
|
+
async function changeTheme(nextTheme) {
|
|
27684
|
+
setTheme(nextTheme);
|
|
27685
|
+
await saveSidePanelThemePreference(nextTheme);
|
|
27686
|
+
}
|
|
27687
|
+
async function changeLocale(nextLocale) {
|
|
27688
|
+
await saveExtensionLocalePreference(nextLocale);
|
|
27689
|
+
setLocale(nextLocale);
|
|
27690
|
+
}
|
|
27626
27691
|
async function disconnect() {
|
|
27627
27692
|
await revokeAndForgetProfile();
|
|
27628
27693
|
setProfile(void 0);
|
|
@@ -27634,7 +27699,7 @@ function SidePanelApp() {
|
|
|
27634
27699
|
setError("");
|
|
27635
27700
|
try {
|
|
27636
27701
|
const local = await discoverLocalGateway({ force: true });
|
|
27637
|
-
if (!local) throw new Error("
|
|
27702
|
+
if (!local) throw new Error(t("errorNoLocalGateway"));
|
|
27638
27703
|
setLocalInvitation(local.invitation);
|
|
27639
27704
|
await connect(local.invitation);
|
|
27640
27705
|
} catch (cause) {
|
|
@@ -27664,44 +27729,96 @@ function SidePanelApp() {
|
|
|
27664
27729
|
] }),
|
|
27665
27730
|
state !== "online" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "status", children: [
|
|
27666
27731
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `status-dot ${error ? "error" : ""}` }),
|
|
27667
|
-
state === "pairing" ? "
|
|
27668
|
-
] }) : null
|
|
27732
|
+
state === "pairing" ? t("statusPairing") : state === "loading" ? t("statusStarting") : t("statusSetupRequired")
|
|
27733
|
+
] }) : null,
|
|
27734
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "header-actions", children: [
|
|
27735
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
27736
|
+
"button",
|
|
27737
|
+
{
|
|
27738
|
+
ref: settingsTrigger,
|
|
27739
|
+
className: "header-icon-button",
|
|
27740
|
+
onClick: () => setSettingsOpen((open) => !open),
|
|
27741
|
+
title: t("settings"),
|
|
27742
|
+
"aria-label": t("settings"),
|
|
27743
|
+
"aria-expanded": settingsOpen,
|
|
27744
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsIcon, {})
|
|
27745
|
+
}
|
|
27746
|
+
),
|
|
27747
|
+
settingsOpen ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: settingsMenu, className: "settings-menu", children: [
|
|
27748
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "settings-menu-title", children: t("settings") }),
|
|
27749
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "settings-group", children: [
|
|
27750
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "settings-label", children: [
|
|
27751
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SunIcon, {}),
|
|
27752
|
+
t("appearance")
|
|
27753
|
+
] }),
|
|
27754
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "settings-options", children: [
|
|
27755
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: theme === "light" ? "active" : "", onClick: () => void changeTheme("light"), children: [
|
|
27756
|
+
t("themeLight"),
|
|
27757
|
+
theme === "light" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckIcon, {}) : null
|
|
27758
|
+
] }),
|
|
27759
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: theme === "dark" ? "active" : "", onClick: () => void changeTheme("dark"), children: [
|
|
27760
|
+
t("themeDark"),
|
|
27761
|
+
theme === "dark" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckIcon, {}) : null
|
|
27762
|
+
] })
|
|
27763
|
+
] })
|
|
27764
|
+
] }),
|
|
27765
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "settings-group", children: [
|
|
27766
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "settings-label", children: [
|
|
27767
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(GlobeIcon, {}),
|
|
27768
|
+
t("language")
|
|
27769
|
+
] }),
|
|
27770
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "settings-options", children: [
|
|
27771
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: locale === "zh-CN" ? "active" : "", onClick: () => void changeLocale("zh-CN"), children: [
|
|
27772
|
+
t("languageChinese"),
|
|
27773
|
+
locale === "zh-CN" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckIcon, {}) : null
|
|
27774
|
+
] }),
|
|
27775
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: locale === "en" ? "active" : "", onClick: () => void changeLocale("en"), children: [
|
|
27776
|
+
t("languageEnglish"),
|
|
27777
|
+
locale === "en" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckIcon, {}) : null
|
|
27778
|
+
] })
|
|
27779
|
+
] })
|
|
27780
|
+
] }),
|
|
27781
|
+
state === "online" && profile ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "settings-disconnect", onClick: () => void disconnect(), title: t("disconnectGateway", profile.gatewayName), children: t("disconnect") }) : null
|
|
27782
|
+
] }) : null
|
|
27783
|
+
] })
|
|
27669
27784
|
] }),
|
|
27670
27785
|
state !== "online" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "center", children: [
|
|
27671
|
-
state === "loading" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "muted", children: "
|
|
27786
|
+
state === "loading" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "muted", children: t("loading") }) : null,
|
|
27672
27787
|
state === "unpaired" || state === "pairing" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "card", children: [
|
|
27673
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { children: "
|
|
27788
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { children: t("connectToXopc") }),
|
|
27674
27789
|
localInvitation ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
27675
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "muted", children: "
|
|
27676
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary local-connect", onClick: () => void connect(localInvitation), disabled: state === "pairing", children: state === "pairing" ? "
|
|
27677
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pairing-divider", children: "
|
|
27790
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "muted", children: t("localGatewayFound") }),
|
|
27791
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary local-connect", onClick: () => void connect(localInvitation), disabled: state === "pairing", children: state === "pairing" ? t("connecting") : t("retryLocalConnection") }),
|
|
27792
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pairing-divider", children: t("pairingLinkDivider") })
|
|
27678
27793
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
27679
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "muted", children: "
|
|
27680
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary local-connect", onClick: () => void connectLocalGateway(), disabled: state === "pairing", children: state === "pairing" ? "
|
|
27681
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pairing-divider", children: "
|
|
27794
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "muted", children: t("connectGatewayHelp") }),
|
|
27795
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary local-connect", onClick: () => void connectLocalGateway(), disabled: state === "pairing", children: state === "pairing" ? t("connecting") : t("connectLocalGateway") }),
|
|
27796
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pairing-divider", children: t("pairingLinkDivider") })
|
|
27682
27797
|
] }),
|
|
27683
27798
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "field", children: [
|
|
27684
|
-
"
|
|
27799
|
+
t("pairingLink"),
|
|
27685
27800
|
/* @__PURE__ */ jsxRuntimeExports.jsx("textarea", { rows: 4, value: invitation, onChange: (event) => setInvitation(event.target.value), disabled: state === "pairing" })
|
|
27686
27801
|
] }),
|
|
27687
27802
|
confirmationCode ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
27688
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "muted", children: "
|
|
27803
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "muted", children: t("confirmGatewayCode") }),
|
|
27689
27804
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "approval-code", children: confirmationCode })
|
|
27690
27805
|
] }) : null,
|
|
27691
27806
|
error ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "error-text", children: error }) : null,
|
|
27692
27807
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "actions", children: [
|
|
27693
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary", onClick: () => void connect(invitation, nextOrigin), disabled: !invitation.trim() || state === "pairing", children: state === "pairing" ? "
|
|
27694
|
-
invitation ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => void cancelPairing(), disabled: state === "pairing", children: "
|
|
27808
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary", onClick: () => void connect(invitation, nextOrigin), disabled: !invitation.trim() || state === "pairing", children: state === "pairing" ? t("waitingForApproval") : nextOrigin ? t("allowGatewayAndContinue", new URL(nextOrigin).host) : t("connect") }),
|
|
27809
|
+
invitation ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => void cancelPairing(), disabled: state === "pairing", children: t("cancelPairing") }) : null
|
|
27695
27810
|
] })
|
|
27696
27811
|
] }) : null
|
|
27697
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChatPanel, {})
|
|
27698
|
-
state === "online" && profile ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "disconnect-link", onClick: disconnect, title: `Disconnect ${profile.gatewayName}`, children: "Disconnect" }) : null
|
|
27812
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChatPanel, {})
|
|
27699
27813
|
] });
|
|
27700
27814
|
}
|
|
27701
27815
|
|
|
27702
27816
|
const root = document.getElementById("root");
|
|
27703
27817
|
if (!root) throw new Error("Side Panel root is missing");
|
|
27704
|
-
|
|
27818
|
+
const [locale, theme] = await Promise.all([
|
|
27819
|
+
loadExtensionLocalePreference(),
|
|
27820
|
+
loadSidePanelThemePreference()
|
|
27821
|
+
]);
|
|
27705
27822
|
clientExports.createRoot(root).render(
|
|
27706
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.StrictMode, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SidePanelApp, {}) })
|
|
27823
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.StrictMode, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SidePanelApp, { initialLocale: locale, initialTheme: theme }) })
|
|
27707
27824
|
);
|