@xopcai/xopc 0.0.265 → 0.0.267
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/dist/assets/{auth-CknJ00ae.js → auth-D_IL6naL.js} +603 -203
- package/dist/browser-ext/dist/assets/sidepanel-CEPaVLjr.css +155 -0
- package/dist/browser-ext/dist/background.js +698 -169
- package/dist/browser-ext/dist/sidepanel.html +3 -3
- package/dist/browser-ext/dist/sidepanel.js +148 -391
- package/dist/browser-ext/manifest.json +3 -6
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DRTTU2H3.js → agent-avatar-dicebear-ZrSAMchm.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-BsXF7LVi.js → agent-defaults-settings-panel-DiNFN8qS.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-DpjWfxYx.js → agents-Bu6Hf59K.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-33Mc81h2.js → app-management-settings-panel-D-L6yjS7.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-C8JECSiJ.js → appearance-settings-BW5eb53j.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-t64FcxIZ.js → apps-page-CiQIdz3N.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-PzZ6SzfY.js → archive-plugin-DwXvu1p9.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-OhLL6K__.js → attachment-load-DqU2BYBp.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BpAYwuvx.js → automations-page-C7qoj9Sd.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-B6aTT5IC.js → automations-workspace-CIARTLHO.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-B5XpGsHg.js → binary-plugins-CfplDak2.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BgEhoTnN.js → block-editor-CzLs38ru.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-CBLunDRH.js → browser-automations-page-_SKi8s9b.js} +1 -1
- package/dist/gateway/static/root/assets/browser-settings-page-DTdx66sX.js +8 -0
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-DftNnICK.js → capabilities-settings-panel-Ck9U0Olx.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-CpuWa5qu.js → channels-settings-I_vDpbnl.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-mnPsS_GJ.js → chat-terminal-dock-snvAu3hJ.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-D3nHGnNV.js → connectors-page-BmKTnzo1.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-expression-NcGBvIfe.js → cron-expression-BhGZSbT6.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-BrVcl7H5.js → date-picker-Cep5f9b-.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker--edd48Y9.js → dependency-picker-BzSEBQku.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-vuyyb6I6.js → desktop-pet-BwX_6Gah.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DWredJwO.js → desktop-pet-settings-WrbVsU2b.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CtBW4ebj.js → extension-debug-page-BdXSwtAZ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CsUrmtW7.js → extension-page-I95ukbRb.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BUd31AuK.js → extension-settings-page-8zUisBay.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-C6FQv7op.js → gateway-settings-DGj5b9Yv.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-CDo1Gjp2.js → heartbeat-settings-BGQxU-Ug.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-D3_uvVJY.js → home-page-BZPpK0A3.js} +1 -1
- package/dist/gateway/static/root/assets/{index-Dpu7EKTm.js → index-D2OtD9Wa.js} +8 -8
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CNVmrCrV.js → keyboard-shortcuts-settings-BUe_om99.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-B0IVDvs-.js → local-app-workbench-page-CbQnffS9.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-DvkarvLt.js → local-apps-page-BZaLzfms.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-BknY0vZf.js → logs-page-WWCHqW_x.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-DW6hJINQ.js → management-settings-Duf8w-Bl.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DYautOWY.js → media-plugins-2-QfzHmg.js} +1 -1
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-Dgu03cv-.js → mobile-pairing-wizard-DRaVIAt1.js} +1 -1
- package/dist/gateway/static/root/assets/{note-detail-panel-Cv9uH6Jq.js → note-detail-panel-BT-fWGxX.js} +3 -3
- package/dist/gateway/static/root/assets/{notes-page-DcIAiYJn.js → notes-page-C4705PzN.js} +1 -1
- package/dist/gateway/static/root/assets/{page-tabs-DF6Q5XvA.js → page-tabs-DaZ7QpNO.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CQJH_jAN.js → preview-open-alternatives-CWEuqCmv.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-D65JfNSw.js → project-detail-page-BZegJ6an.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-BfWF7Sz-.js → projects-page-B7hUHeLI.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-DA1g4CUD.js → remote-access-hub-BE9hZpdh.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-0-bFSBB8.js → runtime-tools-settings-panel-CslkSM-m.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-csGbhTUr.js → schema-form-B2gvVrBq.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-DXPBNhrZ.js → sessions-page-DmAAPMo1.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CvBocGDA.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-YdrdY8B3.js → settings-form-section-CmlnuSO3.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Cv9waRn3.js → settings-page-DWWgyelT.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-DPf-_05Z.js → setup-status-panel-CJrN3m1o.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-DBoEHTPn.js → share-preview-page-C12oyIKk.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-BQP5yNcO.js → shares-settings-D4BtSiLq.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-B5T8cgjq.js → skill-reload-api-CzKGn056.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-D1G8h2Lt.js → skills-page-yhW7LLqk.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-BNZYTop7.js → skills-page.utils-FaTlq8t-.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-ByuppbHi.js → system-settings-panel-CMrkoJLN.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-DNmkrF6y.js → task-detail-page-BUaO62cy.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-CxWGpbwr.js → tunnel-api-C2tAZaJz.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-B0l4qubU.js → use-autosave-BsDRt4QI.js} +1 -1
- package/dist/gateway/static/root/assets/{user-model-page-DMsI6YI7.js → user-model-page-Dy8h1SSJ.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-Bcz7boJg.js → voice-api-key-field-CS5heYMP.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-Dujq1j_u.js → work-discovery-overlay-BeSz5Th5.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CxNYbLNB.js → workflow-run-setup-panel-BebW0CDK.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-Dk1jK2nv.js → workflows-page-CU8jFgPF.js} +1 -1
- package/dist/gateway/static/root/index.html +1 -1
- package/dist/package.js +1 -1
- package/dist/packages/browser-control-contract/src/index.js +30 -1
- package/dist/src/agent/agent-manager.js +4 -4
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/external-tools/endpoint-provider.js +3 -1
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
- package/dist/src/agent/service.js +2 -2
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/agent/tools/factory.js +1 -1
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/oauth/xopc-cloud.js +1 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +2 -2
- package/dist/src/browser/automations/runtime-service.d.ts +2 -0
- package/dist/src/browser/automations/runtime-service.js +1 -1
- package/dist/src/browser/drivers/create-driver.d.ts +2 -1
- package/dist/src/browser/drivers/create-driver.js +4 -6
- package/dist/src/browser/drivers/extension-driver.d.ts +7 -2
- package/dist/src/browser/enrollment.d.ts +8 -0
- package/dist/src/browser/enrollment.js +25 -0
- package/dist/src/browser/extension-identity.d.ts +2 -0
- package/dist/src/browser/extension-identity.js +5 -0
- package/dist/src/browser/native-messaging-host.d.ts +6 -3
- package/dist/src/browser/native-messaging-host.js +23 -5
- package/dist/src/browser/providers/browser-ext-install.d.ts +4 -1
- package/dist/src/browser/providers/browser-ext-install.js +47 -8
- package/dist/src/browser/providers/extension.js +1 -1
- package/dist/src/browser/providers/realtime-extension.d.ts +29 -0
- package/dist/src/browser/providers/realtime-extension.js +83 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/config/index.js +4 -4
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/endpoint-tools/policy.js +10 -3
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/hono/app.js +6 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/browser.js +20 -30
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/security/origin-check.js +5 -0
- package/dist/src/gateway/service/config-coordinator.d.ts +0 -2
- package/dist/src/gateway/service/config-coordinator.js +1 -3
- package/dist/src/gateway/service.d.ts +0 -11
- package/dist/src/gateway/service.js +5 -83
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/storage/sqlite/device-pairing-approval.js +24 -3
- package/dist/src/storage/sqlite/device-pairing-repository.d.ts +10 -1
- package/dist/src/storage/sqlite/device-pairing-repository.js +6 -5
- package/dist/src/storage/sqlite/migrations/157_browser_endpoint_principals.sql +50 -0
- package/dist/src/storage/sqlite/migrations/158_browser_native_enrollment.sql +4 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/work-discovery/service.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +3 -3
- package/dist/browser-ext/dist/assets/sidepanel-C69P3v9u.css +0 -113
- package/dist/gateway/static/root/assets/browser-settings-page-CSfpPCuD.js +0 -8
- package/dist/gateway/static/root/assets/settings-advanced-gate-DxeZm67O.js +0 -1
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>xopc</title>
|
|
7
|
-
<script type="module" crossorigin src="
|
|
8
|
-
<link rel="modulepreload" crossorigin href="
|
|
9
|
-
<link rel="stylesheet" crossorigin href="
|
|
7
|
+
<script type="module" crossorigin src="./sidepanel.js"></script>
|
|
8
|
+
<link rel="modulepreload" crossorigin href="./assets/auth-D_IL6naL.js">
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/sidepanel-CEPaVLjr.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { R as RealtimeClient, i as gatewayFetch, a as activeTabId, f as currentTabDescriptor, T as TAB_BINDING_PREFIX, j as getAccessProfile, P as PENDING_CONTEXT_KEY, d as captureTabWithPermission, b as captureTabPage, r as readProfile, g as discoverLocalGateway, p as pairGateway, s as setAutoConnectEnabled, l as revokeAndForgetProfile } from './assets/auth-D_IL6naL.js';
|
|
2
2
|
|
|
3
3
|
true &&(function polyfill() {
|
|
4
4
|
const relList = document.createElement("link").relList;
|
|
@@ -17345,369 +17345,6 @@ function requireClient () {
|
|
|
17345
17345
|
|
|
17346
17346
|
var clientExports = requireClient();
|
|
17347
17347
|
|
|
17348
|
-
const REALTIME_PROTOCOL_VERSION = 1;
|
|
17349
|
-
const REALTIME_HEARTBEAT_INTERVAL_MS = 15e3;
|
|
17350
|
-
const REALTIME_HEARTBEAT_TIMEOUT_MS = 45e3;
|
|
17351
|
-
const realtimeClientKindSchema = _enum([
|
|
17352
|
-
"web",
|
|
17353
|
-
"desktop",
|
|
17354
|
-
"mobile",
|
|
17355
|
-
"browser_extension",
|
|
17356
|
-
"tui",
|
|
17357
|
-
"mcp"
|
|
17358
|
-
]);
|
|
17359
|
-
const realtimeTopicSchema = string().min(1).max(512);
|
|
17360
|
-
const realtimeEventNameSchema = string().regex(/^[a-z][a-z0-9_.-]*$/).max(160);
|
|
17361
|
-
const messageIdSchema = uuid();
|
|
17362
|
-
const timestampSchema = number().int().nonnegative();
|
|
17363
|
-
const sequenceSchema = number().int().positive();
|
|
17364
|
-
const envelope = (kind, payload) => strictObject({
|
|
17365
|
-
protocolVersion: literal(REALTIME_PROTOCOL_VERSION),
|
|
17366
|
-
messageId: messageIdSchema,
|
|
17367
|
-
kind: literal(kind),
|
|
17368
|
-
sentAt: timestampSchema,
|
|
17369
|
-
payload
|
|
17370
|
-
});
|
|
17371
|
-
const realtimeSubscriptionSchema = strictObject({
|
|
17372
|
-
topic: realtimeTopicSchema,
|
|
17373
|
-
afterSeq: number().int().nonnegative().optional()
|
|
17374
|
-
});
|
|
17375
|
-
discriminatedUnion("kind", [
|
|
17376
|
-
envelope("realtime.hello", strictObject({
|
|
17377
|
-
ticket: string().min(32).max(512),
|
|
17378
|
-
clientId: string().min(1).max(160),
|
|
17379
|
-
clientKind: realtimeClientKindSchema,
|
|
17380
|
-
subscriptions: array(realtimeSubscriptionSchema).max(100).default([]),
|
|
17381
|
-
endpoint: endpointHelloPayloadSchema.optional()
|
|
17382
|
-
})),
|
|
17383
|
-
envelope("realtime.subscribe", strictObject({
|
|
17384
|
-
subscriptions: array(realtimeSubscriptionSchema).min(1).max(100)
|
|
17385
|
-
})),
|
|
17386
|
-
envelope("realtime.unsubscribe", strictObject({
|
|
17387
|
-
topics: array(realtimeTopicSchema).min(1).max(100)
|
|
17388
|
-
})),
|
|
17389
|
-
envelope("realtime.ping", strictObject({})),
|
|
17390
|
-
envelope("endpoint.message", clientEndpointMessageSchema)
|
|
17391
|
-
]);
|
|
17392
|
-
const realtimeEventPayloadSchema = strictObject({
|
|
17393
|
-
topic: realtimeTopicSchema,
|
|
17394
|
-
seq: sequenceSchema,
|
|
17395
|
-
event: realtimeEventNameSchema,
|
|
17396
|
-
data: unknown()
|
|
17397
|
-
});
|
|
17398
|
-
const serverRealtimeMessageSchema = discriminatedUnion("kind", [
|
|
17399
|
-
envelope("realtime.ready", strictObject({
|
|
17400
|
-
connectionId: uuid(),
|
|
17401
|
-
heartbeatIntervalMs: literal(REALTIME_HEARTBEAT_INTERVAL_MS),
|
|
17402
|
-
heartbeatTimeoutMs: literal(REALTIME_HEARTBEAT_TIMEOUT_MS),
|
|
17403
|
-
endpoint: strictObject({
|
|
17404
|
-
endpointId: string().min(1).max(160),
|
|
17405
|
-
turnToken: string().min(32).max(160)
|
|
17406
|
-
}).optional()
|
|
17407
|
-
})),
|
|
17408
|
-
envelope("realtime.event", realtimeEventPayloadSchema),
|
|
17409
|
-
envelope("realtime.subscribed", strictObject({
|
|
17410
|
-
topic: realtimeTopicSchema,
|
|
17411
|
-
cursor: number().int().nonnegative()
|
|
17412
|
-
})),
|
|
17413
|
-
envelope("realtime.gap", strictObject({
|
|
17414
|
-
topic: realtimeTopicSchema,
|
|
17415
|
-
requestedSeq: number().int().nonnegative(),
|
|
17416
|
-
earliestSeq: sequenceSchema,
|
|
17417
|
-
recoverable: boolean()
|
|
17418
|
-
})),
|
|
17419
|
-
envelope("realtime.pong", strictObject({})),
|
|
17420
|
-
envelope("realtime.error", strictObject({
|
|
17421
|
-
code: string().min(1).max(80),
|
|
17422
|
-
message: string().min(1).max(500)
|
|
17423
|
-
})),
|
|
17424
|
-
envelope("endpoint.message", serverEndpointMessageSchema)
|
|
17425
|
-
]);
|
|
17426
|
-
function parseServerRealtimeMessage(value) {
|
|
17427
|
-
return serverRealtimeMessageSchema.parse(value);
|
|
17428
|
-
}
|
|
17429
|
-
|
|
17430
|
-
function frameText(data) {
|
|
17431
|
-
if (typeof data === "string") return data;
|
|
17432
|
-
if (data instanceof ArrayBuffer) return new TextDecoder().decode(data);
|
|
17433
|
-
if (ArrayBuffer.isView(data)) {
|
|
17434
|
-
const bytes = Uint8Array.from(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
|
|
17435
|
-
return new TextDecoder().decode(bytes);
|
|
17436
|
-
}
|
|
17437
|
-
throw new Error("Realtime server sent a non-text frame");
|
|
17438
|
-
}
|
|
17439
|
-
function isNonRetryableCloseCode(code) {
|
|
17440
|
-
return code === 1009 || code === 4400 || code === 4401 || code === 4413;
|
|
17441
|
-
}
|
|
17442
|
-
class RealtimeClient {
|
|
17443
|
-
constructor(options) {
|
|
17444
|
-
this.options = options;
|
|
17445
|
-
}
|
|
17446
|
-
options;
|
|
17447
|
-
desiredSubscriptions = /* @__PURE__ */ new Map();
|
|
17448
|
-
cursors = /* @__PURE__ */ new Map();
|
|
17449
|
-
socket;
|
|
17450
|
-
reconnectTimer;
|
|
17451
|
-
heartbeatTimer;
|
|
17452
|
-
connectionTimer;
|
|
17453
|
-
ticketAbort;
|
|
17454
|
-
generation = 0;
|
|
17455
|
-
reconnectAttempts = 0;
|
|
17456
|
-
shouldReconnect = false;
|
|
17457
|
-
ready = false;
|
|
17458
|
-
lastServerMessageAt = 0;
|
|
17459
|
-
endpointBinding;
|
|
17460
|
-
reconnectWhenSocketOpens = false;
|
|
17461
|
-
connect() {
|
|
17462
|
-
if (this.shouldReconnect) return;
|
|
17463
|
-
this.shouldReconnect = true;
|
|
17464
|
-
void this.open(false);
|
|
17465
|
-
}
|
|
17466
|
-
disconnect() {
|
|
17467
|
-
this.shouldReconnect = false;
|
|
17468
|
-
this.reconnectWhenSocketOpens = false;
|
|
17469
|
-
this.generation += 1;
|
|
17470
|
-
this.clearTimers();
|
|
17471
|
-
this.ready = false;
|
|
17472
|
-
this.endpointBinding?.onDisconnected?.();
|
|
17473
|
-
this.socket?.close(1e3, "Client disconnected");
|
|
17474
|
-
this.socket = void 0;
|
|
17475
|
-
this.options.onStateChange?.("disconnected");
|
|
17476
|
-
}
|
|
17477
|
-
reconnect() {
|
|
17478
|
-
this.reconnectWhenSocketOpens = false;
|
|
17479
|
-
this.generation += 1;
|
|
17480
|
-
this.clearTimers();
|
|
17481
|
-
this.ready = false;
|
|
17482
|
-
this.endpointBinding?.onDisconnected?.();
|
|
17483
|
-
this.socket?.close(1e3, "Client reconnecting");
|
|
17484
|
-
this.socket = void 0;
|
|
17485
|
-
this.reconnectAttempts = 0;
|
|
17486
|
-
this.shouldReconnect = true;
|
|
17487
|
-
void this.open(true);
|
|
17488
|
-
}
|
|
17489
|
-
subscribe(topic, afterSeq) {
|
|
17490
|
-
this.desiredSubscriptions.set(topic, afterSeq);
|
|
17491
|
-
if (afterSeq !== void 0) this.cursors.set(topic, afterSeq);
|
|
17492
|
-
if (this.ready) {
|
|
17493
|
-
this.sendSubscriptions([{ topic, afterSeq: this.cursors.get(topic) ?? afterSeq }]);
|
|
17494
|
-
}
|
|
17495
|
-
}
|
|
17496
|
-
unsubscribe(topic) {
|
|
17497
|
-
this.desiredSubscriptions.delete(topic);
|
|
17498
|
-
if (this.ready) this.send(this.clientMessage("realtime.unsubscribe", { topics: [topic] }));
|
|
17499
|
-
}
|
|
17500
|
-
sendEndpointMessage(message) {
|
|
17501
|
-
if (!this.ready) throw new Error("Realtime connection is not ready");
|
|
17502
|
-
this.send(this.clientMessage("endpoint.message", message));
|
|
17503
|
-
}
|
|
17504
|
-
setEndpoint(binding) {
|
|
17505
|
-
this.endpointBinding = binding;
|
|
17506
|
-
this.refreshEndpointConnection();
|
|
17507
|
-
}
|
|
17508
|
-
clearEndpoint(binding) {
|
|
17509
|
-
if (binding && this.endpointBinding !== binding) return;
|
|
17510
|
-
const previous = this.endpointBinding;
|
|
17511
|
-
this.endpointBinding = void 0;
|
|
17512
|
-
previous?.onDisconnected?.();
|
|
17513
|
-
this.refreshEndpointConnection();
|
|
17514
|
-
}
|
|
17515
|
-
refreshEndpointConnection() {
|
|
17516
|
-
if (!this.shouldReconnect) return;
|
|
17517
|
-
if (this.socket?.readyState === 0) {
|
|
17518
|
-
this.reconnectWhenSocketOpens = true;
|
|
17519
|
-
return;
|
|
17520
|
-
}
|
|
17521
|
-
this.reconnect();
|
|
17522
|
-
}
|
|
17523
|
-
async open(reconnecting) {
|
|
17524
|
-
const generation = ++this.generation;
|
|
17525
|
-
const timeoutMs = this.options.connectionTimeoutMs ?? 15e3;
|
|
17526
|
-
const ticketAbort = new AbortController();
|
|
17527
|
-
this.ticketAbort?.abort();
|
|
17528
|
-
this.ticketAbort = ticketAbort;
|
|
17529
|
-
let socket;
|
|
17530
|
-
let closed = false;
|
|
17531
|
-
let messageQueue;
|
|
17532
|
-
const failAttempt = (error, retry = true) => {
|
|
17533
|
-
if (closed || generation !== this.generation) return;
|
|
17534
|
-
closed = true;
|
|
17535
|
-
this.clearConnectionTimer();
|
|
17536
|
-
ticketAbort.abort();
|
|
17537
|
-
if (this.ticketAbort === ticketAbort) this.ticketAbort = void 0;
|
|
17538
|
-
this.ready = false;
|
|
17539
|
-
this.endpointBinding?.onDisconnected?.();
|
|
17540
|
-
this.clearHeartbeat();
|
|
17541
|
-
if (this.socket === socket) this.socket = void 0;
|
|
17542
|
-
if (socket) {
|
|
17543
|
-
socket.onopen = null;
|
|
17544
|
-
socket.onmessage = null;
|
|
17545
|
-
socket.onerror = null;
|
|
17546
|
-
socket.onclose = null;
|
|
17547
|
-
socket.close(4e3, error.slice(0, 120));
|
|
17548
|
-
}
|
|
17549
|
-
if (this.shouldReconnect && retry) this.scheduleReconnect(error);
|
|
17550
|
-
else if (this.shouldReconnect) {
|
|
17551
|
-
this.shouldReconnect = false;
|
|
17552
|
-
this.options.onStateChange?.("error", error);
|
|
17553
|
-
} else this.options.onStateChange?.("disconnected");
|
|
17554
|
-
};
|
|
17555
|
-
this.connectionTimer = setTimeout(() => failAttempt("Realtime connection timed out"), timeoutMs);
|
|
17556
|
-
this.options.onStateChange?.(reconnecting ? "reconnecting" : "connecting");
|
|
17557
|
-
try {
|
|
17558
|
-
const [ticket, endpoint] = await Promise.all([
|
|
17559
|
-
this.options.issueTicket(ticketAbort.signal),
|
|
17560
|
-
this.endpointBinding?.createHello()
|
|
17561
|
-
]);
|
|
17562
|
-
if (closed || !this.shouldReconnect || generation !== this.generation) return;
|
|
17563
|
-
socket = this.options.createWebSocket(this.options.getWebSocketUrl());
|
|
17564
|
-
this.socket = socket;
|
|
17565
|
-
socket.onopen = () => {
|
|
17566
|
-
if (generation !== this.generation) return;
|
|
17567
|
-
if (this.reconnectWhenSocketOpens) {
|
|
17568
|
-
this.reconnect();
|
|
17569
|
-
return;
|
|
17570
|
-
}
|
|
17571
|
-
const subscriptions = [...this.desiredSubscriptions].map(([topic, afterSeq]) => ({
|
|
17572
|
-
topic,
|
|
17573
|
-
afterSeq: this.cursors.get(topic) ?? afterSeq
|
|
17574
|
-
}));
|
|
17575
|
-
this.send(this.clientMessage("realtime.hello", {
|
|
17576
|
-
ticket,
|
|
17577
|
-
clientId: this.options.clientId,
|
|
17578
|
-
clientKind: this.options.clientKind,
|
|
17579
|
-
subscriptions,
|
|
17580
|
-
...endpoint ? { endpoint } : {}
|
|
17581
|
-
}));
|
|
17582
|
-
};
|
|
17583
|
-
socket.onmessage = (event) => {
|
|
17584
|
-
if (generation !== this.generation) return;
|
|
17585
|
-
const process = () => {
|
|
17586
|
-
if (closed || generation !== this.generation) return;
|
|
17587
|
-
return this.handleServerMessage(frameText(event.data));
|
|
17588
|
-
};
|
|
17589
|
-
if (!messageQueue) {
|
|
17590
|
-
try {
|
|
17591
|
-
const pending = process();
|
|
17592
|
-
if (!pending) return;
|
|
17593
|
-
const current2 = pending.catch((error) => failAttempt(error instanceof Error ? error.message : "Invalid realtime server message")).then(() => void 0);
|
|
17594
|
-
messageQueue = current2;
|
|
17595
|
-
void current2.finally(() => {
|
|
17596
|
-
if (messageQueue === current2) messageQueue = void 0;
|
|
17597
|
-
});
|
|
17598
|
-
} catch (error) {
|
|
17599
|
-
failAttempt(error instanceof Error ? error.message : "Invalid realtime server message");
|
|
17600
|
-
}
|
|
17601
|
-
return;
|
|
17602
|
-
}
|
|
17603
|
-
const current = messageQueue.then(process).catch((error) => failAttempt(error instanceof Error ? error.message : "Invalid realtime server message")).then(() => void 0);
|
|
17604
|
-
messageQueue = current;
|
|
17605
|
-
void current.finally(() => {
|
|
17606
|
-
if (messageQueue === current) messageQueue = void 0;
|
|
17607
|
-
});
|
|
17608
|
-
};
|
|
17609
|
-
socket.onerror = () => {
|
|
17610
|
-
};
|
|
17611
|
-
socket.onclose = (event) => {
|
|
17612
|
-
failAttempt(
|
|
17613
|
-
event.reason || `WebSocket closed (${event.code ?? 0})`,
|
|
17614
|
-
!isNonRetryableCloseCode(event.code)
|
|
17615
|
-
);
|
|
17616
|
-
};
|
|
17617
|
-
} catch (error) {
|
|
17618
|
-
failAttempt(error instanceof Error ? error.message : "Realtime connection failed");
|
|
17619
|
-
}
|
|
17620
|
-
}
|
|
17621
|
-
handleServerMessage(text) {
|
|
17622
|
-
const message = parseServerRealtimeMessage(JSON.parse(text));
|
|
17623
|
-
this.lastServerMessageAt = Date.now();
|
|
17624
|
-
if (message.kind === "realtime.ready") {
|
|
17625
|
-
this.ready = true;
|
|
17626
|
-
this.reconnectAttempts = 0;
|
|
17627
|
-
this.clearConnectionTimer();
|
|
17628
|
-
this.ticketAbort = void 0;
|
|
17629
|
-
this.options.onStateChange?.("connected");
|
|
17630
|
-
if (message.payload.endpoint) this.endpointBinding?.onReady(message.payload.endpoint);
|
|
17631
|
-
this.clearHeartbeat();
|
|
17632
|
-
this.heartbeatTimer = setInterval(() => {
|
|
17633
|
-
if (!this.ready) return;
|
|
17634
|
-
if (Date.now() - this.lastServerMessageAt >= message.payload.heartbeatTimeoutMs) {
|
|
17635
|
-
this.reconnect();
|
|
17636
|
-
return;
|
|
17637
|
-
}
|
|
17638
|
-
this.send(this.clientMessage("realtime.ping", {}));
|
|
17639
|
-
}, message.payload.heartbeatIntervalMs);
|
|
17640
|
-
} else if (message.kind === "realtime.event") {
|
|
17641
|
-
const cursor = this.cursors.get(message.payload.topic);
|
|
17642
|
-
if (cursor !== void 0 && message.payload.seq <= cursor) return;
|
|
17643
|
-
this.options.onEvent?.(message.payload);
|
|
17644
|
-
this.cursors.set(message.payload.topic, message.payload.seq);
|
|
17645
|
-
} else if (message.kind === "realtime.subscribed") {
|
|
17646
|
-
this.cursors.set(message.payload.topic, message.payload.cursor);
|
|
17647
|
-
} else if (message.kind === "realtime.gap") {
|
|
17648
|
-
this.cursors.set(message.payload.topic, message.payload.earliestSeq - 1);
|
|
17649
|
-
return this.options.onGap?.(message.payload);
|
|
17650
|
-
} else if (message.kind === "realtime.error") {
|
|
17651
|
-
this.options.onStateChange?.("error", message.payload.message);
|
|
17652
|
-
} else if (message.kind === "endpoint.message") {
|
|
17653
|
-
this.endpointBinding?.onMessage(message.payload);
|
|
17654
|
-
this.options.onEndpointMessage?.(message.payload);
|
|
17655
|
-
}
|
|
17656
|
-
}
|
|
17657
|
-
sendSubscriptions(subscriptions) {
|
|
17658
|
-
this.send(this.clientMessage("realtime.subscribe", { subscriptions }));
|
|
17659
|
-
}
|
|
17660
|
-
clientMessage(kind, payload) {
|
|
17661
|
-
const messageId = this.options.createMessageId?.() ?? globalThis.crypto?.randomUUID?.();
|
|
17662
|
-
if (!messageId) throw new Error("RealtimeClient requires createMessageId when crypto.randomUUID is unavailable");
|
|
17663
|
-
return {
|
|
17664
|
-
protocolVersion: REALTIME_PROTOCOL_VERSION,
|
|
17665
|
-
messageId,
|
|
17666
|
-
kind,
|
|
17667
|
-
sentAt: Date.now(),
|
|
17668
|
-
payload
|
|
17669
|
-
};
|
|
17670
|
-
}
|
|
17671
|
-
send(message) {
|
|
17672
|
-
if (!this.socket || this.socket.readyState !== 1) return;
|
|
17673
|
-
this.socket.send(JSON.stringify(message));
|
|
17674
|
-
}
|
|
17675
|
-
scheduleReconnect(error) {
|
|
17676
|
-
if (!this.shouldReconnect) return;
|
|
17677
|
-
this.reconnectAttempts += 1;
|
|
17678
|
-
const max = this.options.maxReconnectAttempts;
|
|
17679
|
-
if (max !== void 0 && this.reconnectAttempts > max) {
|
|
17680
|
-
this.shouldReconnect = false;
|
|
17681
|
-
this.options.onStateChange?.("error", error);
|
|
17682
|
-
return;
|
|
17683
|
-
}
|
|
17684
|
-
this.options.onStateChange?.("reconnecting", error);
|
|
17685
|
-
const cap = Math.min(3e4, 1e3 * 2 ** Math.min(this.reconnectAttempts - 1, 5));
|
|
17686
|
-
const delay = Math.round(cap * (0.5 + Math.random() * 0.5));
|
|
17687
|
-
if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
|
|
17688
|
-
this.reconnectTimer = setTimeout(() => {
|
|
17689
|
-
this.reconnectTimer = void 0;
|
|
17690
|
-
void this.open(true);
|
|
17691
|
-
}, delay);
|
|
17692
|
-
}
|
|
17693
|
-
clearHeartbeat() {
|
|
17694
|
-
if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
|
|
17695
|
-
this.heartbeatTimer = void 0;
|
|
17696
|
-
}
|
|
17697
|
-
clearTimers() {
|
|
17698
|
-
if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
|
|
17699
|
-
this.reconnectTimer = void 0;
|
|
17700
|
-
this.clearConnectionTimer();
|
|
17701
|
-
this.ticketAbort?.abort();
|
|
17702
|
-
this.ticketAbort = void 0;
|
|
17703
|
-
this.clearHeartbeat();
|
|
17704
|
-
}
|
|
17705
|
-
clearConnectionTimer() {
|
|
17706
|
-
if (this.connectionTimer) clearTimeout(this.connectionTimer);
|
|
17707
|
-
this.connectionTimer = void 0;
|
|
17708
|
-
}
|
|
17709
|
-
}
|
|
17710
|
-
|
|
17711
17348
|
const CLIENT_ID_KEY = "xopc.browser.client-id";
|
|
17712
17349
|
const ACTIVE_CHAT_KEY = "xopc.browser.active-chat";
|
|
17713
17350
|
const CURSOR_PREFIX = "xopc.browser.cursor.";
|
|
@@ -17785,6 +17422,13 @@ class BrowserChatClient {
|
|
|
17785
17422
|
turnClaim;
|
|
17786
17423
|
runTopic;
|
|
17787
17424
|
recoveringOutbox = false;
|
|
17425
|
+
endpointPoll;
|
|
17426
|
+
onRuntimeMessage = (message) => {
|
|
17427
|
+
if (message.type !== "browser/endpoint-ready" || !message.claim) return;
|
|
17428
|
+
this.turnClaim = message.claim;
|
|
17429
|
+
this.update({ endpointReady: true, error: void 0 });
|
|
17430
|
+
void this.recoverOutbox();
|
|
17431
|
+
};
|
|
17788
17432
|
snapshot = {
|
|
17789
17433
|
connection: "idle",
|
|
17790
17434
|
endpointReady: false,
|
|
@@ -17800,7 +17444,7 @@ class BrowserChatClient {
|
|
|
17800
17444
|
}
|
|
17801
17445
|
async start() {
|
|
17802
17446
|
await this.prepare();
|
|
17803
|
-
|
|
17447
|
+
chrome.runtime.onMessage.addListener(this.onRuntimeMessage);
|
|
17804
17448
|
const id = await clientId();
|
|
17805
17449
|
this.realtime = new RealtimeClient({
|
|
17806
17450
|
clientId: id,
|
|
@@ -17836,23 +17480,13 @@ class BrowserChatClient {
|
|
|
17836
17480
|
if (topic === this.runTopic) await this.reloadMessages();
|
|
17837
17481
|
}
|
|
17838
17482
|
});
|
|
17839
|
-
this.realtime.setEndpoint({
|
|
17840
|
-
createHello: createBrowserEndpointHello,
|
|
17841
|
-
onReady: ({ endpointId, turnToken }) => {
|
|
17842
|
-
this.turnClaim = { endpointId, token: turnToken };
|
|
17843
|
-
this.update({ endpointReady: true, error: void 0 });
|
|
17844
|
-
void this.recoverOutbox();
|
|
17845
|
-
},
|
|
17846
|
-
onMessage: () => {
|
|
17847
|
-
},
|
|
17848
|
-
onDisconnected: () => {
|
|
17849
|
-
this.turnClaim = void 0;
|
|
17850
|
-
this.update({ endpointReady: false });
|
|
17851
|
-
}
|
|
17852
|
-
});
|
|
17853
17483
|
this.realtime.subscribe("gateway");
|
|
17854
17484
|
this.realtime.subscribe("sessions");
|
|
17855
17485
|
this.realtime.connect();
|
|
17486
|
+
await this.refreshEndpointClaim();
|
|
17487
|
+
this.endpointPoll = setInterval(() => {
|
|
17488
|
+
void this.refreshEndpointClaim();
|
|
17489
|
+
}, 1e3);
|
|
17856
17490
|
await Promise.all([this.loadSessions(), this.loadModels()]);
|
|
17857
17491
|
const tabId = await activeTabId();
|
|
17858
17492
|
const tabKey = tabId === void 0 ? void 0 : `${TAB_SESSION_PREFIX}${tabId}`;
|
|
@@ -17863,11 +17497,22 @@ class BrowserChatClient {
|
|
|
17863
17497
|
}
|
|
17864
17498
|
}
|
|
17865
17499
|
stop() {
|
|
17500
|
+
chrome.runtime.onMessage.removeListener(this.onRuntimeMessage);
|
|
17501
|
+
if (this.endpointPoll) clearInterval(this.endpointPoll);
|
|
17502
|
+
this.endpointPoll = void 0;
|
|
17866
17503
|
this.realtime?.disconnect();
|
|
17867
17504
|
this.realtime = void 0;
|
|
17868
17505
|
this.turnClaim = void 0;
|
|
17869
17506
|
this.update({ endpointReady: false });
|
|
17870
17507
|
}
|
|
17508
|
+
async refreshEndpointClaim() {
|
|
17509
|
+
const response = await chrome.runtime.sendMessage({ type: "browser/get-endpoint-claim" }).catch(() => void 0);
|
|
17510
|
+
this.turnClaim = response?.claim;
|
|
17511
|
+
this.update({
|
|
17512
|
+
endpointReady: Boolean(this.turnClaim),
|
|
17513
|
+
...response?.error ? { error: response.error } : {}
|
|
17514
|
+
});
|
|
17515
|
+
}
|
|
17871
17516
|
async loadSessions(search) {
|
|
17872
17517
|
const params = new URLSearchParams({ channel: "webchat", limit: "30" });
|
|
17873
17518
|
if (search?.trim()) params.set("search", search.trim());
|
|
@@ -18018,8 +17663,6 @@ class BrowserChatClient {
|
|
|
18018
17663
|
async bindActiveTab(mode) {
|
|
18019
17664
|
const sessionKey = this.snapshot.sessionKey;
|
|
18020
17665
|
if (!sessionKey || !this.turnClaim) throw new Error("Open a chat and wait for the browser endpoint");
|
|
18021
|
-
const debuggerGranted = await chrome.permissions.request({ permissions: ["debugger"] });
|
|
18022
|
-
if (!debuggerGranted) throw new Error("Chrome debugger permission is required to control this tab");
|
|
18023
17666
|
const descriptor = await currentTabDescriptor();
|
|
18024
17667
|
const result = await json(await gatewayFetch(
|
|
18025
17668
|
`/api/browser/tab-bindings/${encodeURIComponent(sessionKey)}`,
|
|
@@ -18758,6 +18401,78 @@ function ChatPanel() {
|
|
|
18758
18401
|
] });
|
|
18759
18402
|
}
|
|
18760
18403
|
|
|
18404
|
+
function isSidePanelTheme(value) {
|
|
18405
|
+
return value === "light" || value === "dark";
|
|
18406
|
+
}
|
|
18407
|
+
function applySidePanelTheme(theme) {
|
|
18408
|
+
document.documentElement.dataset.theme = theme;
|
|
18409
|
+
document.documentElement.style.colorScheme = theme;
|
|
18410
|
+
}
|
|
18411
|
+
function applySystemSidePanelTheme() {
|
|
18412
|
+
applySidePanelTheme(globalThis.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light");
|
|
18413
|
+
}
|
|
18414
|
+
function isGatewayThemePageUrl(value, gatewayUrl) {
|
|
18415
|
+
try {
|
|
18416
|
+
const url = new URL(value);
|
|
18417
|
+
if (url.protocol === "http:" && (url.hostname === "127.0.0.1" || url.hostname === "localhost")) {
|
|
18418
|
+
return true;
|
|
18419
|
+
}
|
|
18420
|
+
return Boolean(gatewayUrl && url.origin === new URL(gatewayUrl).origin);
|
|
18421
|
+
} catch {
|
|
18422
|
+
return false;
|
|
18423
|
+
}
|
|
18424
|
+
}
|
|
18425
|
+
async function pageTheme(tabId) {
|
|
18426
|
+
try {
|
|
18427
|
+
const [{ result } = {}] = await chrome.scripting.executeScript({
|
|
18428
|
+
target: { tabId },
|
|
18429
|
+
func: () => ({
|
|
18430
|
+
theme: document.documentElement.dataset.theme
|
|
18431
|
+
})
|
|
18432
|
+
});
|
|
18433
|
+
return isSidePanelTheme(result?.theme) ? result.theme : void 0;
|
|
18434
|
+
} catch {
|
|
18435
|
+
return void 0;
|
|
18436
|
+
}
|
|
18437
|
+
}
|
|
18438
|
+
async function syncSidePanelTheme(gatewayUrl) {
|
|
18439
|
+
const tabs = (await chrome.tabs.query({})).filter((tab) => {
|
|
18440
|
+
return typeof tab.id === "number" && Boolean(tab.url) && isGatewayThemePageUrl(tab.url, gatewayUrl);
|
|
18441
|
+
}).sort((left, right) => Number(right.active) - Number(left.active));
|
|
18442
|
+
for (const tab of tabs) {
|
|
18443
|
+
const theme = await pageTheme(tab.id);
|
|
18444
|
+
if (theme) {
|
|
18445
|
+
applySidePanelTheme(theme);
|
|
18446
|
+
return;
|
|
18447
|
+
}
|
|
18448
|
+
}
|
|
18449
|
+
}
|
|
18450
|
+
function watchSidePanelTheme(gatewayUrl) {
|
|
18451
|
+
const sync = () => {
|
|
18452
|
+
void syncSidePanelTheme(gatewayUrl);
|
|
18453
|
+
};
|
|
18454
|
+
const onUpdated = (_tabId, change) => {
|
|
18455
|
+
if (change.status === "complete" || change.url) sync();
|
|
18456
|
+
};
|
|
18457
|
+
const onVisibilityChange = () => {
|
|
18458
|
+
if (document.visibilityState === "visible") sync();
|
|
18459
|
+
};
|
|
18460
|
+
sync();
|
|
18461
|
+
window.addEventListener("focus", sync);
|
|
18462
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
18463
|
+
chrome.tabs.onActivated.addListener(sync);
|
|
18464
|
+
chrome.tabs.onUpdated.addListener(onUpdated);
|
|
18465
|
+
return () => {
|
|
18466
|
+
window.removeEventListener("focus", sync);
|
|
18467
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
18468
|
+
chrome.tabs.onActivated.removeListener(sync);
|
|
18469
|
+
chrome.tabs.onUpdated.removeListener(onUpdated);
|
|
18470
|
+
};
|
|
18471
|
+
}
|
|
18472
|
+
|
|
18473
|
+
async function reconnectBrowserBridge() {
|
|
18474
|
+
await chrome.runtime.sendMessage({ type: "browser/reconnect" }).catch(() => void 0);
|
|
18475
|
+
}
|
|
18761
18476
|
function SidePanelApp() {
|
|
18762
18477
|
const [profile, setProfile] = reactExports.useState();
|
|
18763
18478
|
const [pairingLink, setPairingLink] = reactExports.useState("");
|
|
@@ -18765,21 +18480,44 @@ function SidePanelApp() {
|
|
|
18765
18480
|
const [state, setState] = reactExports.useState("loading");
|
|
18766
18481
|
const [error, setError] = reactExports.useState("");
|
|
18767
18482
|
const [localPairingLink, setLocalPairingLink] = reactExports.useState("");
|
|
18483
|
+
const initializationStarted = reactExports.useRef(false);
|
|
18768
18484
|
reactExports.useEffect(() => {
|
|
18769
|
-
|
|
18770
|
-
|
|
18771
|
-
|
|
18772
|
-
|
|
18773
|
-
|
|
18774
|
-
|
|
18485
|
+
if (initializationStarted.current) return;
|
|
18486
|
+
initializationStarted.current = true;
|
|
18487
|
+
void (async () => {
|
|
18488
|
+
const stored = await readProfile();
|
|
18489
|
+
if (stored) {
|
|
18490
|
+
await reconnectBrowserBridge();
|
|
18491
|
+
setProfile(stored);
|
|
18492
|
+
setState("online");
|
|
18493
|
+
return;
|
|
18775
18494
|
}
|
|
18776
|
-
|
|
18495
|
+
const local = await discoverLocalGateway();
|
|
18496
|
+
if (!local) {
|
|
18497
|
+
setState("unpaired");
|
|
18498
|
+
return;
|
|
18499
|
+
}
|
|
18500
|
+
setLocalPairingLink(local.pairingLink);
|
|
18501
|
+
setState("pairing");
|
|
18502
|
+
try {
|
|
18503
|
+
const paired = await pairGateway(local.pairingLink, setConfirmationCode);
|
|
18504
|
+
await reconnectBrowserBridge();
|
|
18505
|
+
setProfile(paired);
|
|
18506
|
+
setState("online");
|
|
18507
|
+
} catch (cause) {
|
|
18508
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
18509
|
+
setState("unpaired");
|
|
18510
|
+
}
|
|
18511
|
+
})();
|
|
18777
18512
|
}, []);
|
|
18513
|
+
reactExports.useEffect(() => watchSidePanelTheme(profile?.gatewayUrl), [profile?.gatewayUrl]);
|
|
18778
18514
|
async function connect(link = pairingLink) {
|
|
18779
18515
|
setState("pairing");
|
|
18780
18516
|
setError("");
|
|
18781
18517
|
try {
|
|
18782
18518
|
const paired = await pairGateway(link, setConfirmationCode);
|
|
18519
|
+
await setAutoConnectEnabled(true);
|
|
18520
|
+
await reconnectBrowserBridge();
|
|
18783
18521
|
setProfile(paired);
|
|
18784
18522
|
setState("online");
|
|
18785
18523
|
} catch (cause) {
|
|
@@ -18790,8 +18528,22 @@ function SidePanelApp() {
|
|
|
18790
18528
|
async function disconnect() {
|
|
18791
18529
|
await revokeAndForgetProfile();
|
|
18792
18530
|
setProfile(void 0);
|
|
18531
|
+
setLocalPairingLink("");
|
|
18793
18532
|
setState("unpaired");
|
|
18794
18533
|
}
|
|
18534
|
+
async function connectLocalGateway() {
|
|
18535
|
+
setState("pairing");
|
|
18536
|
+
setError("");
|
|
18537
|
+
try {
|
|
18538
|
+
const local = await discoverLocalGateway({ force: true });
|
|
18539
|
+
if (!local) throw new Error("No local xopc Gateway was found");
|
|
18540
|
+
setLocalPairingLink(local.pairingLink);
|
|
18541
|
+
await connect(local.pairingLink);
|
|
18542
|
+
} catch (cause) {
|
|
18543
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
18544
|
+
setState("unpaired");
|
|
18545
|
+
}
|
|
18546
|
+
}
|
|
18795
18547
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("main", { className: "shell", children: [
|
|
18796
18548
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("header", { className: "header", children: [
|
|
18797
18549
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "brand", children: "xopc" }),
|
|
@@ -18805,10 +18557,14 @@ function SidePanelApp() {
|
|
|
18805
18557
|
state === "unpaired" || state === "pairing" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "card", children: [
|
|
18806
18558
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { children: "Connect to xopc" }),
|
|
18807
18559
|
localPairingLink ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
18808
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "muted", children: "A local xopc Gateway was found.
|
|
18809
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary local-connect", onClick: () => void connect(localPairingLink), disabled: state === "pairing", children: state === "pairing" ? "
|
|
18560
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "muted", children: "A local xopc Gateway was found. xopc connects automatically on this computer." }),
|
|
18561
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary local-connect", onClick: () => void connect(localPairingLink), disabled: state === "pairing", children: state === "pairing" ? "Connecting…" : "Retry local connection" }),
|
|
18810
18562
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pairing-divider", children: "or use a pairing link" })
|
|
18811
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.
|
|
18563
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
18564
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "muted", children: "Connect to a local Gateway, or paste a pairing link for another Gateway." }),
|
|
18565
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary local-connect", onClick: () => void connectLocalGateway(), disabled: state === "pairing", children: state === "pairing" ? "Connecting…" : "Connect local Gateway" }),
|
|
18566
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pairing-divider", children: "or use a pairing link" })
|
|
18567
|
+
] }),
|
|
18812
18568
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "field", children: [
|
|
18813
18569
|
"Pairing link",
|
|
18814
18570
|
/* @__PURE__ */ jsxRuntimeExports.jsx("textarea", { rows: 4, value: pairingLink, onChange: (event) => setPairingLink(event.target.value), disabled: state === "pairing" })
|
|
@@ -18827,6 +18583,7 @@ function SidePanelApp() {
|
|
|
18827
18583
|
|
|
18828
18584
|
const root = document.getElementById("root");
|
|
18829
18585
|
if (!root) throw new Error("Side Panel root is missing");
|
|
18586
|
+
applySystemSidePanelTheme();
|
|
18830
18587
|
clientExports.createRoot(root).render(
|
|
18831
18588
|
/* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.StrictMode, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SidePanelApp, {}) })
|
|
18832
18589
|
);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"minimum_chrome_version": "120",
|
|
4
4
|
"name": "xopc",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.267",
|
|
6
6
|
"description": "Chat with xopc and explicitly share or control the current page.",
|
|
7
7
|
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqnpr4vpLC/nmvy+wiOWk3SWlp2nEZkFijfk8ivGw7StNZgCK90nOMvwhdEtlkk3GOWDvdVnq8HxCsM3UNQ8FnGUyerpH1FJXqXuradxeHf8ZxFjiQU/mIWfnKbUuONWQORon3/pigyoXoK/VUXgg0Wbm/rbVwsS0bv+25R6m+mZgBspOLeKuoH7ivhL+48WV6POtMBsFPZweY26477EM7ukh+56Ff5ENevB8ymxBBn7qK5ZoeZd2a23U8ioX5TsHfe6fnrjitPWjIxD8G0NoKQxcaa/Mo+xs+T6UiLKxP0wjz5bm7jB5H+CXtkRJqzBWUB0h+RSLJckzZfA8BAJrRwIDAQAB",
|
|
8
8
|
"permissions": [
|
|
@@ -12,17 +12,14 @@
|
|
|
12
12
|
"tabs",
|
|
13
13
|
"tabGroups",
|
|
14
14
|
"activeTab",
|
|
15
|
-
"alarms",
|
|
16
15
|
"storage",
|
|
17
|
-
"nativeMessaging"
|
|
16
|
+
"nativeMessaging",
|
|
17
|
+
"debugger"
|
|
18
18
|
],
|
|
19
19
|
"host_permissions": [
|
|
20
20
|
"http://127.0.0.1/*",
|
|
21
21
|
"http://localhost/*"
|
|
22
22
|
],
|
|
23
|
-
"optional_permissions": [
|
|
24
|
-
"debugger"
|
|
25
|
-
],
|
|
26
23
|
"optional_host_permissions": [
|
|
27
24
|
"http://*/*",
|
|
28
25
|
"https://*/*"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "telegram",
|
|
3
3
|
"name": "Telegram Channel",
|
|
4
4
|
"description": "Bundled Telegram Bot channel (private workspace sources; ships inside @xopcai/xopc dist/)",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.267",
|
|
6
6
|
"kind": "channel",
|
|
7
7
|
"main": "src/index.js",
|
|
8
8
|
"channels": [
|