@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.
Files changed (148) hide show
  1. package/dist/browser-ext/dist/assets/{auth-CknJ00ae.js → auth-D_IL6naL.js} +603 -203
  2. package/dist/browser-ext/dist/assets/sidepanel-CEPaVLjr.css +155 -0
  3. package/dist/browser-ext/dist/background.js +698 -169
  4. package/dist/browser-ext/dist/sidepanel.html +3 -3
  5. package/dist/browser-ext/dist/sidepanel.js +148 -391
  6. package/dist/browser-ext/manifest.json +3 -6
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DRTTU2H3.js → agent-avatar-dicebear-ZrSAMchm.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-BsXF7LVi.js → agent-defaults-settings-panel-DiNFN8qS.js} +1 -1
  10. package/dist/gateway/static/root/assets/{agents-DpjWfxYx.js → agents-Bu6Hf59K.js} +1 -1
  11. package/dist/gateway/static/root/assets/{app-management-settings-panel-33Mc81h2.js → app-management-settings-panel-D-L6yjS7.js} +1 -1
  12. package/dist/gateway/static/root/assets/{appearance-settings-C8JECSiJ.js → appearance-settings-BW5eb53j.js} +1 -1
  13. package/dist/gateway/static/root/assets/{apps-page-t64FcxIZ.js → apps-page-CiQIdz3N.js} +1 -1
  14. package/dist/gateway/static/root/assets/{archive-plugin-PzZ6SzfY.js → archive-plugin-DwXvu1p9.js} +1 -1
  15. package/dist/gateway/static/root/assets/{attachment-load-OhLL6K__.js → attachment-load-DqU2BYBp.js} +1 -1
  16. package/dist/gateway/static/root/assets/{automations-page-BpAYwuvx.js → automations-page-C7qoj9Sd.js} +1 -1
  17. package/dist/gateway/static/root/assets/{automations-workspace-B6aTT5IC.js → automations-workspace-CIARTLHO.js} +1 -1
  18. package/dist/gateway/static/root/assets/{binary-plugins-B5XpGsHg.js → binary-plugins-CfplDak2.js} +1 -1
  19. package/dist/gateway/static/root/assets/{block-editor-BgEhoTnN.js → block-editor-CzLs38ru.js} +1 -1
  20. package/dist/gateway/static/root/assets/{browser-automations-page-CBLunDRH.js → browser-automations-page-_SKi8s9b.js} +1 -1
  21. package/dist/gateway/static/root/assets/browser-settings-page-DTdx66sX.js +8 -0
  22. package/dist/gateway/static/root/assets/{capabilities-settings-panel-DftNnICK.js → capabilities-settings-panel-Ck9U0Olx.js} +1 -1
  23. package/dist/gateway/static/root/assets/{channels-settings-CpuWa5qu.js → channels-settings-I_vDpbnl.js} +1 -1
  24. package/dist/gateway/static/root/assets/{chat-terminal-dock-mnPsS_GJ.js → chat-terminal-dock-snvAu3hJ.js} +1 -1
  25. package/dist/gateway/static/root/assets/{connectors-page-D3nHGnNV.js → connectors-page-BmKTnzo1.js} +1 -1
  26. package/dist/gateway/static/root/assets/{cron-expression-NcGBvIfe.js → cron-expression-BhGZSbT6.js} +1 -1
  27. package/dist/gateway/static/root/assets/{date-picker-BrVcl7H5.js → date-picker-Cep5f9b-.js} +1 -1
  28. package/dist/gateway/static/root/assets/{dependency-picker--edd48Y9.js → dependency-picker-BzSEBQku.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-vuyyb6I6.js → desktop-pet-BwX_6Gah.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-settings-DWredJwO.js → desktop-pet-settings-WrbVsU2b.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-debug-page-CtBW4ebj.js → extension-debug-page-BdXSwtAZ.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-CsUrmtW7.js → extension-page-I95ukbRb.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-BUd31AuK.js → extension-settings-page-8zUisBay.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-settings-C6FQv7op.js → gateway-settings-DGj5b9Yv.js} +1 -1
  35. package/dist/gateway/static/root/assets/{heartbeat-settings-CDo1Gjp2.js → heartbeat-settings-BGQxU-Ug.js} +1 -1
  36. package/dist/gateway/static/root/assets/{home-page-D3_uvVJY.js → home-page-BZPpK0A3.js} +1 -1
  37. package/dist/gateway/static/root/assets/{index-Dpu7EKTm.js → index-D2OtD9Wa.js} +8 -8
  38. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CNVmrCrV.js → keyboard-shortcuts-settings-BUe_om99.js} +1 -1
  39. package/dist/gateway/static/root/assets/{local-app-workbench-page-B0IVDvs-.js → local-app-workbench-page-CbQnffS9.js} +1 -1
  40. package/dist/gateway/static/root/assets/{local-apps-page-DvkarvLt.js → local-apps-page-BZaLzfms.js} +1 -1
  41. package/dist/gateway/static/root/assets/{logs-page-BknY0vZf.js → logs-page-WWCHqW_x.js} +1 -1
  42. package/dist/gateway/static/root/assets/{management-settings-DW6hJINQ.js → management-settings-Duf8w-Bl.js} +1 -1
  43. package/dist/gateway/static/root/assets/{media-plugins-DYautOWY.js → media-plugins-2-QfzHmg.js} +1 -1
  44. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-Dgu03cv-.js → mobile-pairing-wizard-DRaVIAt1.js} +1 -1
  45. package/dist/gateway/static/root/assets/{note-detail-panel-Cv9uH6Jq.js → note-detail-panel-BT-fWGxX.js} +3 -3
  46. package/dist/gateway/static/root/assets/{notes-page-DcIAiYJn.js → notes-page-C4705PzN.js} +1 -1
  47. package/dist/gateway/static/root/assets/{page-tabs-DF6Q5XvA.js → page-tabs-DaZ7QpNO.js} +1 -1
  48. package/dist/gateway/static/root/assets/{preview-open-alternatives-CQJH_jAN.js → preview-open-alternatives-CWEuqCmv.js} +1 -1
  49. package/dist/gateway/static/root/assets/{project-detail-page-D65JfNSw.js → project-detail-page-BZegJ6an.js} +1 -1
  50. package/dist/gateway/static/root/assets/{projects-page-BfWF7Sz-.js → projects-page-B7hUHeLI.js} +1 -1
  51. package/dist/gateway/static/root/assets/{remote-access-hub-DA1g4CUD.js → remote-access-hub-BE9hZpdh.js} +1 -1
  52. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-0-bFSBB8.js → runtime-tools-settings-panel-CslkSM-m.js} +1 -1
  53. package/dist/gateway/static/root/assets/{schema-form-csGbhTUr.js → schema-form-B2gvVrBq.js} +1 -1
  54. package/dist/gateway/static/root/assets/{sessions-page-DXPBNhrZ.js → sessions-page-DmAAPMo1.js} +1 -1
  55. package/dist/gateway/static/root/assets/settings-advanced-gate-CvBocGDA.js +1 -0
  56. package/dist/gateway/static/root/assets/{settings-form-section-YdrdY8B3.js → settings-form-section-CmlnuSO3.js} +1 -1
  57. package/dist/gateway/static/root/assets/{settings-page-Cv9waRn3.js → settings-page-DWWgyelT.js} +1 -1
  58. package/dist/gateway/static/root/assets/{setup-status-panel-DPf-_05Z.js → setup-status-panel-CJrN3m1o.js} +1 -1
  59. package/dist/gateway/static/root/assets/{share-preview-page-DBoEHTPn.js → share-preview-page-C12oyIKk.js} +1 -1
  60. package/dist/gateway/static/root/assets/{shares-settings-BQP5yNcO.js → shares-settings-D4BtSiLq.js} +1 -1
  61. package/dist/gateway/static/root/assets/{skill-reload-api-B5T8cgjq.js → skill-reload-api-CzKGn056.js} +1 -1
  62. package/dist/gateway/static/root/assets/{skills-page-D1G8h2Lt.js → skills-page-yhW7LLqk.js} +1 -1
  63. package/dist/gateway/static/root/assets/{skills-page.utils-BNZYTop7.js → skills-page.utils-FaTlq8t-.js} +1 -1
  64. package/dist/gateway/static/root/assets/{system-settings-panel-ByuppbHi.js → system-settings-panel-CMrkoJLN.js} +1 -1
  65. package/dist/gateway/static/root/assets/{task-detail-page-DNmkrF6y.js → task-detail-page-BUaO62cy.js} +1 -1
  66. package/dist/gateway/static/root/assets/{tunnel-api-CxWGpbwr.js → tunnel-api-C2tAZaJz.js} +1 -1
  67. package/dist/gateway/static/root/assets/{use-autosave-B0l4qubU.js → use-autosave-BsDRt4QI.js} +1 -1
  68. package/dist/gateway/static/root/assets/{user-model-page-DMsI6YI7.js → user-model-page-Dy8h1SSJ.js} +1 -1
  69. package/dist/gateway/static/root/assets/{voice-api-key-field-Bcz7boJg.js → voice-api-key-field-CS5heYMP.js} +1 -1
  70. package/dist/gateway/static/root/assets/{work-discovery-overlay-Dujq1j_u.js → work-discovery-overlay-BeSz5Th5.js} +1 -1
  71. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CxNYbLNB.js → workflow-run-setup-panel-BebW0CDK.js} +1 -1
  72. package/dist/gateway/static/root/assets/{workflows-page-Dk1jK2nv.js → workflows-page-CU8jFgPF.js} +1 -1
  73. package/dist/gateway/static/root/index.html +1 -1
  74. package/dist/package.js +1 -1
  75. package/dist/packages/browser-control-contract/src/index.js +30 -1
  76. package/dist/src/agent/agent-manager.js +4 -4
  77. package/dist/src/agent/background-review/run-background-review.js +1 -1
  78. package/dist/src/agent/embedded/model-runtime.js +1 -1
  79. package/dist/src/agent/embedded/run-for-session.js +1 -1
  80. package/dist/src/agent/external-tools/endpoint-provider.js +3 -1
  81. package/dist/src/agent/image/tool-model-config.js +1 -1
  82. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
  83. package/dist/src/agent/service.js +2 -2
  84. package/dist/src/agent/session/session-inspector.js +1 -1
  85. package/dist/src/agent/skills/hub-lock.js +1 -1
  86. package/dist/src/agent/tasks/task-judge-service.js +3 -3
  87. package/dist/src/agent/tools/factory.js +1 -1
  88. package/dist/src/ai-assist/text-assist.js +1 -1
  89. package/dist/src/auth/credentials.js +2 -2
  90. package/dist/src/auth/oauth/xopc-cloud.js +1 -1
  91. package/dist/src/auth/profiles/store.js +1 -1
  92. package/dist/src/auth/sync-provider-auth.js +2 -2
  93. package/dist/src/browser/automations/runtime-service.d.ts +2 -0
  94. package/dist/src/browser/automations/runtime-service.js +1 -1
  95. package/dist/src/browser/drivers/create-driver.d.ts +2 -1
  96. package/dist/src/browser/drivers/create-driver.js +4 -6
  97. package/dist/src/browser/drivers/extension-driver.d.ts +7 -2
  98. package/dist/src/browser/enrollment.d.ts +8 -0
  99. package/dist/src/browser/enrollment.js +25 -0
  100. package/dist/src/browser/extension-identity.d.ts +2 -0
  101. package/dist/src/browser/extension-identity.js +5 -0
  102. package/dist/src/browser/native-messaging-host.d.ts +6 -3
  103. package/dist/src/browser/native-messaging-host.js +23 -5
  104. package/dist/src/browser/providers/browser-ext-install.d.ts +4 -1
  105. package/dist/src/browser/providers/browser-ext-install.js +47 -8
  106. package/dist/src/browser/providers/extension.js +1 -1
  107. package/dist/src/browser/providers/realtime-extension.d.ts +29 -0
  108. package/dist/src/browser/providers/realtime-extension.js +83 -0
  109. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  110. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  111. package/dist/src/cli/commands/models.js +1 -1
  112. package/dist/src/config/index.js +4 -4
  113. package/dist/src/config/loader.js +2 -2
  114. package/dist/src/config/models-json.js +1 -1
  115. package/dist/src/endpoint-tools/policy.js +10 -3
  116. package/dist/src/extensions/lockfile.js +1 -1
  117. package/dist/src/gateway/agents-admin.js +1 -1
  118. package/dist/src/gateway/file-path-classifier.js +1 -1
  119. package/dist/src/gateway/hono/app.js +6 -1
  120. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  121. package/dist/src/gateway/hono/routes/browser.js +20 -30
  122. package/dist/src/gateway/hono/routes/models.js +1 -1
  123. package/dist/src/gateway/security/origin-check.js +5 -0
  124. package/dist/src/gateway/service/config-coordinator.d.ts +0 -2
  125. package/dist/src/gateway/service/config-coordinator.js +1 -3
  126. package/dist/src/gateway/service.d.ts +0 -11
  127. package/dist/src/gateway/service.js +5 -83
  128. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  129. package/dist/src/providers/index.js +2 -2
  130. package/dist/src/providers/model-registry.js +1 -1
  131. package/dist/src/providers/register-runtime-providers.js +1 -1
  132. package/dist/src/storage/sqlite/device-pairing-approval.js +24 -3
  133. package/dist/src/storage/sqlite/device-pairing-repository.d.ts +10 -1
  134. package/dist/src/storage/sqlite/device-pairing-repository.js +6 -5
  135. package/dist/src/storage/sqlite/migrations/157_browser_endpoint_principals.sql +50 -0
  136. package/dist/src/storage/sqlite/migrations/158_browser_native_enrollment.sql +4 -0
  137. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  138. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  139. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  140. package/dist/src/storage/sqlite/schema.js +1 -1
  141. package/dist/src/tui/tui-startup-resources.js +1 -1
  142. package/dist/src/tui/tui.js +1 -1
  143. package/dist/src/work-discovery/service.js +1 -1
  144. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  145. package/package.json +3 -3
  146. package/dist/browser-ext/dist/assets/sidepanel-C69P3v9u.css +0 -113
  147. package/dist/gateway/static/root/assets/browser-settings-page-CSfpPCuD.js +0 -8
  148. 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="/sidepanel.js"></script>
8
- <link rel="modulepreload" crossorigin href="/assets/auth-CknJ00ae.js">
9
- <link rel="stylesheet" crossorigin href="/assets/sidepanel-C69P3v9u.css">
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 { j as discriminatedUnion, v as strictObject, w as string, n as literal, o as number, _ as _enum, k as endpointHelloPayloadSchema, b as array, f as clientEndpointMessageSchema, x as unknown, y as uuid, c as boolean, t as serverEndpointMessageSchema, q as registerBrowserEndpoint, l as gatewayFetch, g as createBrowserEndpointHello, a as activeTabId, h as currentTabDescriptor, T as TAB_BINDING_PREFIX, m as getAccessProfile, P as PENDING_CONTEXT_KEY, e as captureTabWithPermission, d as captureTabPage, r as readProfile, i as discoverLocalGateway, p as pairGateway, s as revokeAndForgetProfile } from './assets/auth-CknJ00ae.js';
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
- await registerBrowserEndpoint();
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
- void readProfile().then(async (stored) => {
18770
- setProfile(stored);
18771
- setState(stored ? "online" : "unpaired");
18772
- if (!stored) {
18773
- const local = await discoverLocalGateway();
18774
- if (local) setLocalPairingLink(local.pairingLink);
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. Connecting still requires approval in the Gateway." }),
18809
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary local-connect", onClick: () => void connect(localPairingLink), disabled: state === "pairing", children: state === "pairing" ? "Waiting for approval…" : "Connect local xopc" }),
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.jsx("p", { className: "muted", children: "Create a browser pairing link in the xopc Gateway, then paste it here." }),
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.265",
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.265",
5
+ "version": "0.0.267",
6
6
  "kind": "channel",
7
7
  "main": "src/index.js",
8
8
  "channels": [