@xopcai/xopc 0.0.270 → 0.0.272
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-cwEj8rFb.js → auth-C1QI-uMG.js} +65 -14
- package/dist/browser-ext/dist/background.js +23 -2
- package/dist/browser-ext/dist/pairing-handoff.js +51 -0
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +39 -27
- package/dist/browser-ext/manifest.json +12 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-D_0FmdRj.js → activity-store-DffqjeqQ.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-IZvEXak_.js → agent-avatar-dicebear-Cwj4HCYY.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-6CLfLxVc.js +1 -0
- package/dist/gateway/static/root/assets/agents-B6mu64fY.js +1 -0
- package/dist/gateway/static/root/assets/{api-O3TTQ4qN.js → api-CGLdye4i.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Cqqsbzri.js → app-management-settings-panel-BLujSbaw.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DaJyf32s.js → appearance-settings-BXMcueb8.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BEgy4hY3.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-kDPnDTJI.js → archive-plugin-D4bUampf.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CJ3VceKS.js → attachment-load-CBGNA2Ys.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-JwMtU8XB.js → automations-page-dQyolNmy.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-DxRFrmrV.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DzyZXLBX.js → binary-plugins-bbvp81h2.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-kTt3gYIJ.js → block-editor-C8e6Wri4.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-BKohPYR4.js → browser-automation-inputs-oJWJtQa6.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-ktQfFPk-.js → browser-automations-page-CAcJQSjN.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-TLAlqcPo.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-z-K_jrZz.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-Dzrk33aB.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-DrqzYmDr.js → channels-status-swr-CfOPNnVr.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CIFGGLGa.js → chat-terminal-dock-9ZOl92kh.js} +2 -2
- package/dist/gateway/static/root/assets/clock-3-DnrAnuyZ.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-B1dIoRNi.js +2 -0
- package/dist/gateway/static/root/assets/cron-expression-C26e13YU.js +2 -0
- package/dist/gateway/static/root/assets/date-picker-Dj6FRLF9.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-D3vNIjRI.js → dependency-picker-D1q89tVc.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-fQwRb_3p.js → desktop-pet-DfqZBvhp.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DfOJ-GvT.js → desktop-pet-settings-HCEh2MOm.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-CPth92s6.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Cn53jB5-.js → extension-debug-page-C8cAWVoK.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-IDpLCxpC.js → extension-page-5N87Vaym.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-D85SAUFP.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-swr-B7dcmP7Q.js → gateway-config-swr-BjsDnB_n.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-Dqx8PmcT.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-JGhGMhVZ.js → gateway-startup-retry-BIf0eLWX.js} +1 -1
- package/dist/gateway/static/root/assets/git-branch-Dh9uxTot.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-BpDWGE1a.js +1 -0
- package/dist/gateway/static/root/assets/home-page-DJaqpC8-.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-BJLX7Qrh.js → image-generation-api-1m8xTVS_.js} +1 -1
- package/dist/gateway/static/root/assets/index-C6PmD0cK.js +74 -0
- package/dist/gateway/static/root/assets/index-DKy1Qn1_.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CBvMTFFx.js → keyboard-shortcuts-settings-Byy8mCSq.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-l2AEiG2C.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-APCMNDvU.js → local-apps-page-BPo0wBgM.js} +1 -1
- package/dist/gateway/static/root/assets/locale-store-CRNble2Z.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-X5FdLlXK.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-DT6NoIjm.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-BwjpJVPs.js → markdown-view-AglreSOj.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C10byeaa.js → media-plugins-Bzka9qXu.js} +1 -1
- package/dist/gateway/static/root/assets/message-circle-Badhj-4D.js +1 -0
- package/dist/gateway/static/root/assets/message-square-fVE7Ghj1.js +1 -0
- package/dist/gateway/static/root/assets/{messages-D0V_bgRP.js → messages-DH_HCgmw.js} +3 -3
- package/dist/gateway/static/root/assets/note-detail-panel-BUJPoaGZ.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-BwFpWRuo.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-qQ36zncF.js → page-tabs-Ys0p65Lt.js} +1 -1
- package/dist/gateway/static/root/assets/popover-select-Dz_Qis2R.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BiAJvvCo.js → preview-open-alternatives-iknB5xEp.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-card-CcNBqHoH.js → proactive-card-BPZDgNNR.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-page-C3K61jve.js → proactive-page-CxdZR-p2.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CunnDP4w.js → product-open-page-W1o3f-kz.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BU1RKAcy.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-z0X0tL8G.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-0JSegbNl.js → registry-api-DmYFpjsH.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-NNTut2I8.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-bu_mwBTr.js → runtime-tools-settings-panel-DP1XyYO8.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-BE0sgZyz.js → schema-form-BMYKdzsH.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-B6SsHlz5.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BQu8bAcN.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CBo517lV.js → settings-form-section-2LGjz7bu.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DBPimx93.js → settings-page-7DjpC9_C.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Dj9jFWJt.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-DdV75VTe.js → share-preview-page-BxYdSi8c.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CMqE0KuK.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BXqSJymN.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-Cn_-nvRo.js → skills-page-DNEScMZH.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page.utils-q88l65YU.js +1 -0
- package/dist/gateway/static/root/assets/system-settings-panel-8NIssGKj.js +1 -0
- package/dist/gateway/static/root/assets/task-detail-page-L6dp9v2y.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-1wryLgBQ.js → theme-store-BXZG3S25.js} +1 -1
- package/dist/gateway/static/root/assets/tunnel-api-CWsRPM84.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-N_lm4FdD.js → use-autosave-BwQuoTQU.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-D4BucMrZ.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DMsyVfri.js → voice-api-key-field-Bd03Ic0s.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-QWVmiAp3.js → voice-config-api-gggUp3u9.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BC0vAxp1.js → work-discovery-overlay-DF8PR_pK.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Cz9jQIlP.js → workflow-run-setup-panel-BiAAWlir.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DryKUMfA.js +6 -0
- package/dist/gateway/static/root/index.html +15 -11
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/device-pairing.js +2 -1
- package/dist/packages/gateway-contract/src/session-identity.js +37 -0
- package/dist/src/agent/memory/compaction-chunks.d.ts +18 -0
- package/dist/src/agent/memory/compaction-chunks.js +53 -0
- package/dist/src/agent/memory/compaction-request.d.ts +12 -0
- package/dist/src/agent/memory/compaction-request.js +72 -0
- package/dist/src/agent/memory/compaction.d.ts +3 -0
- package/dist/src/agent/memory/compaction.js +166 -118
- package/dist/src/agent/service.js +1 -0
- package/dist/src/browser/native-messaging-host.js +3 -1
- package/dist/src/cli/bin.js +2 -2
- package/dist/src/cli/commands/agent.js +2 -2
- package/dist/src/cli/commands/auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/gateway-ssh-tunnel.js +1 -1
- package/dist/src/cli/commands/models.js +2 -2
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/platform.js +1 -1
- package/dist/src/cli/commands/profile.js +1 -1
- package/dist/src/cli/commands/tunnel.js +6 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/cli/extension-cli-register.js +1 -1
- package/dist/src/config/index.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/app.js +1 -0
- package/dist/src/gateway/hono/middleware/auth.d.ts +1 -2
- package/dist/src/gateway/hono/middleware/auth.js +49 -31
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +11 -15
- package/dist/src/gateway/hono/routes/browser-session.d.ts +3 -0
- package/dist/src/gateway/hono/routes/browser-session.js +43 -0
- package/dist/src/gateway/hono/routes/devices.js +61 -96
- package/dist/src/gateway/hono/routes/exposure.js +3 -7
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/models.js +60 -1
- package/dist/src/gateway/hono/routes/notes.js +3 -7
- package/dist/src/gateway/hono/routes/sessions.js +11 -0
- package/dist/src/gateway/hono/routes/shares.js +8 -20
- package/dist/src/gateway/hono/routes/site-shares.js +4 -8
- package/dist/src/gateway/hono/routes/tunnel.js +13 -13
- package/dist/src/gateway/image-generation-setup.d.ts +17 -0
- package/dist/src/gateway/image-generation-setup.js +30 -21
- package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
- package/dist/src/gateway/rate-limit/buckets.js +10 -0
- package/dist/src/gateway/run-loop.js +1 -1
- package/dist/src/gateway/runtime-config.js +2 -0
- package/dist/src/gateway/security/browser-session.d.ts +5 -0
- package/dist/src/gateway/security/browser-session.js +45 -0
- package/dist/src/gateway/security/gateway-principal.d.ts +1 -0
- package/dist/src/gateway/server.js +1 -1
- package/dist/src/gateway/service.d.ts +1 -0
- package/dist/src/gateway/service.js +11 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/rate-limit/keyed-store.d.ts +3 -0
- package/dist/src/infra/rate-limit/keyed-store.js +9 -2
- package/dist/src/proactive/policy/service.d.ts +1 -1
- package/dist/src/realtime/runtime.d.ts +2 -1
- package/dist/src/realtime/runtime.js +9 -3
- package/dist/src/realtime/tickets.d.ts +1 -0
- package/dist/src/realtime/tickets.js +3 -0
- package/dist/src/session/store.d.ts +2 -0
- package/dist/src/session/store.js +17 -2
- package/dist/src/session/types.d.ts +2 -1
- package/dist/src/storage/sqlite/browser-session-repository.d.ts +17 -0
- package/dist/src/storage/sqlite/browser-session-repository.js +54 -0
- package/dist/src/storage/sqlite/device-pairing-approval.js +2 -1
- package/dist/src/storage/sqlite/device-pairing-repository.d.ts +4 -10
- package/dist/src/storage/sqlite/device-pairing-repository.js +10 -62
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/dist/src/storage/sqlite/migrations/164_browser_sessions.sql +8 -0
- package/dist/src/storage/sqlite/migrations/165_device_pairing_target.sql +40 -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/storage/sqlite/session-identity-sql.d.ts +2 -0
- package/dist/src/storage/sqlite/session-identity-sql.js +18 -0
- package/dist/src/storage/sqlite/session-repository.js +26 -22
- package/dist/src/tunnel/auth-policy.d.ts +3 -0
- package/dist/src/tunnel/auth-policy.js +8 -0
- package/dist/src/tunnel/broker-client.d.ts +5 -15
- package/dist/src/tunnel/broker-client.js +37 -49
- package/dist/src/tunnel/frpc-binary.d.ts +8 -6
- package/dist/src/tunnel/frpc-binary.js +76 -88
- package/dist/src/tunnel/frpc-config.d.ts +2 -1
- package/dist/src/tunnel/frpc-config.js +29 -12
- package/dist/src/tunnel/frpc-release.d.ts +27 -0
- package/dist/src/tunnel/frpc-release.js +30 -0
- package/dist/src/tunnel/gateway-lifecycle.js +8 -2
- package/dist/src/tunnel/index.js +2 -1
- package/dist/src/tunnel/registration-proof.d.ts +19 -0
- package/dist/src/tunnel/registration-proof.js +37 -0
- package/dist/src/tunnel/tunnel-persist.js +3 -1
- package/dist/src/tunnel/tunnel-service.d.ts +1 -0
- package/dist/src/tunnel/tunnel-service.js +35 -8
- package/dist/src/tunnel/tunnel-state.js +11 -5
- package/dist/src/tunnel/tunnel-types.d.ts +2 -0
- package/dist/src/tunnel/well-known.js +5 -1
- package/dist/src/user-context/config.js +2 -2
- package/dist/src/utils/logger/redact.js +4 -0
- package/dist/src/voice/realtime/runtime.d.ts +1 -0
- package/dist/src/voice/realtime/runtime.js +17 -1
- package/dist/src/voice/realtime/runtime.types.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +2 -0
- package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
- package/dist/src/workflows/service/workflow-session-bridge.js +1 -0
- package/package.json +4 -4
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CE3ygr3l.js +0 -1
- package/dist/gateway/static/root/assets/agents-DzG2qw-c.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-B4lX6yoT.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-BiNBewg0.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-Dgdt5uVL.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BpDW-R9f.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-DU4EQnR0.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CfJqy284.js +0 -2
- package/dist/gateway/static/root/assets/cron-expression-BNwbnrEb.js +0 -2
- package/dist/gateway/static/root/assets/date-picker-DKyirU4K.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-B1dds2bP.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-pp9jN0wl.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-B8_zTyev.js +0 -1
- package/dist/gateway/static/root/assets/home-page-g1KdAdLb.js +0 -1
- package/dist/gateway/static/root/assets/index-1zRt56Zt.css +0 -2
- package/dist/gateway/static/root/assets/index-OMnem2nr.js +0 -74
- package/dist/gateway/static/root/assets/local-app-workbench-page-bj75v2ZE.js +0 -2
- package/dist/gateway/static/root/assets/locale-store-BThkG0W5.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-BX7n39zV.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-CM62j8ZX.js +0 -1
- package/dist/gateway/static/root/assets/mobile-pairing-wizard-BCWfwVx3.js +0 -1
- package/dist/gateway/static/root/assets/note-detail-panel-koOqb0gX.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-BH54rY3B.js +0 -8
- package/dist/gateway/static/root/assets/popover-select-CKBYnT3c.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-SL2g8MZY.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BtxazT5J.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BSb7b67A.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-ljcS2KVz.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CR9Y9LQm.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-J3AnooPW.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-AAm4Iwcp.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-pRCjP5sm.js +0 -1
- package/dist/gateway/static/root/assets/skills-page.utils-CfVAc_lu.js +0 -1
- package/dist/gateway/static/root/assets/system-settings-panel-B-pzalp-.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-CmrLy3PO.js +0 -1
- package/dist/gateway/static/root/assets/tunnel-api-Cgpnm2fL.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-u3QLDX6L.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-DA6OOK6X.js +0 -6
|
@@ -5655,6 +5655,7 @@ class RealtimeClient {
|
|
|
5655
5655
|
}
|
|
5656
5656
|
}
|
|
5657
5657
|
|
|
5658
|
+
_enum(["mobile", "browser"]);
|
|
5658
5659
|
const devicePairingKeySchema = strictObject({
|
|
5659
5660
|
kty: literal("EC"),
|
|
5660
5661
|
crv: literal("P-256"),
|
|
@@ -5976,6 +5977,7 @@ async function clearBrowserOutboxes() {
|
|
|
5976
5977
|
}
|
|
5977
5978
|
|
|
5978
5979
|
const PROFILE_KEY = "xopc.browser.profile";
|
|
5980
|
+
const PENDING_PAIRING_LINK_KEY = "xopc.browser.pending-pairing-link";
|
|
5979
5981
|
const AUTO_CONNECT_KEY = "xopc.browser.auto-connect";
|
|
5980
5982
|
const KEY_DATABASE = "xopc-browser-identity";
|
|
5981
5983
|
const KEY_STORE = "identity";
|
|
@@ -6047,18 +6049,34 @@ function randomNonce(bytes = 24) {
|
|
|
6047
6049
|
function createRefreshToken() {
|
|
6048
6050
|
return `xopc_rt_${crypto.randomUUID()}_${randomNonce(32)}`;
|
|
6049
6051
|
}
|
|
6050
|
-
function
|
|
6052
|
+
function parseBrowserPairingLink(value) {
|
|
6051
6053
|
const url = new URL(value.trim());
|
|
6054
|
+
if (url.protocol !== "https:" || url.hostname !== "link.xopc.ai" || url.pathname !== "/connect") {
|
|
6055
|
+
throw new Error("Pairing link is not from xopc");
|
|
6056
|
+
}
|
|
6052
6057
|
const encoded = new URLSearchParams(url.hash.slice(1)).get("p");
|
|
6053
6058
|
if (!encoded) throw new Error("Pairing link is invalid");
|
|
6054
6059
|
const payload = decodeJson(encoded);
|
|
6055
|
-
if (payload.version !== 3 || !payload.gatewayId || !payload.pairingToken || !payload.gatewayPublicKey) {
|
|
6060
|
+
if (payload.version !== 3 || payload.targetKind !== "browser" || !payload.gatewayId || !payload.pairingToken || !payload.gatewayPublicKey || !Array.isArray(payload.routes)) {
|
|
6056
6061
|
throw new Error("Pairing link version is not supported");
|
|
6057
6062
|
}
|
|
6058
6063
|
if (payload.expiresAt <= Date.now()) throw new Error("Pairing link has expired");
|
|
6059
6064
|
if (!payload.routes.length) throw new Error("Pairing link has no Gateway route");
|
|
6065
|
+
for (const route of payload.routes) {
|
|
6066
|
+
const routeUrl = new URL(route.url);
|
|
6067
|
+
if (!route.id || !["http:", "https:"].includes(routeUrl.protocol)) {
|
|
6068
|
+
throw new Error("Pairing link has an invalid Gateway route");
|
|
6069
|
+
}
|
|
6070
|
+
}
|
|
6060
6071
|
return payload;
|
|
6061
6072
|
}
|
|
6073
|
+
async function takePendingPairingLink() {
|
|
6074
|
+
const stored = await chrome.storage.session.get(PENDING_PAIRING_LINK_KEY);
|
|
6075
|
+
const link = stored[PENDING_PAIRING_LINK_KEY];
|
|
6076
|
+
if (typeof link !== "string") return void 0;
|
|
6077
|
+
await chrome.storage.session.remove(PENDING_PAIRING_LINK_KEY);
|
|
6078
|
+
return link;
|
|
6079
|
+
}
|
|
6062
6080
|
function openIdentityDatabase() {
|
|
6063
6081
|
return new Promise((resolve, reject) => {
|
|
6064
6082
|
const request = indexedDB.open(KEY_DATABASE, 1);
|
|
@@ -6143,14 +6161,27 @@ async function requestGatewayOriginPermission(origin) {
|
|
|
6143
6161
|
throw new Error("Gateway site permission was not granted");
|
|
6144
6162
|
}
|
|
6145
6163
|
}
|
|
6164
|
+
class GatewayHttpError extends Error {
|
|
6165
|
+
constructor(message, status) {
|
|
6166
|
+
super(message);
|
|
6167
|
+
this.status = status;
|
|
6168
|
+
this.name = "GatewayHttpError";
|
|
6169
|
+
}
|
|
6170
|
+
status;
|
|
6171
|
+
}
|
|
6146
6172
|
async function post(origin, path, body) {
|
|
6147
6173
|
const response = await fetch(`${origin}${path}`, {
|
|
6148
6174
|
method: "POST",
|
|
6149
6175
|
headers: { "Content-Type": "application/json" },
|
|
6150
6176
|
body: JSON.stringify(body)
|
|
6151
6177
|
});
|
|
6152
|
-
const json = await response.json();
|
|
6153
|
-
if (!response.ok)
|
|
6178
|
+
const json = await response.json().catch(() => ({}));
|
|
6179
|
+
if (!response.ok) {
|
|
6180
|
+
throw new GatewayHttpError(
|
|
6181
|
+
json.error?.code ?? json.error?.message ?? `Gateway returned ${response.status}`,
|
|
6182
|
+
response.status
|
|
6183
|
+
);
|
|
6184
|
+
}
|
|
6154
6185
|
return json;
|
|
6155
6186
|
}
|
|
6156
6187
|
async function signedPairingRequest(pair, payload, origin, requestId, action, completion) {
|
|
@@ -6186,7 +6217,7 @@ async function signedPairingRequest(pair, payload, origin, requestId, action, co
|
|
|
6186
6217
|
}
|
|
6187
6218
|
return decoded;
|
|
6188
6219
|
}
|
|
6189
|
-
async function refreshAccessToken(gatewayUrl, refreshToken, pair) {
|
|
6220
|
+
async function refreshAccessToken(gatewayUrl, refreshToken, pair, gateway) {
|
|
6190
6221
|
const nextRefreshToken = createRefreshToken();
|
|
6191
6222
|
const requestId = crypto.randomUUID();
|
|
6192
6223
|
const timestamp = Date.now();
|
|
@@ -6207,22 +6238,42 @@ ${nextRefreshToken}`;
|
|
|
6207
6238
|
nonce,
|
|
6208
6239
|
signature
|
|
6209
6240
|
});
|
|
6210
|
-
if (
|
|
6241
|
+
if (typeof response.signedPayload !== "string" || typeof response.signature !== "string" || !await verifyGateway(gateway.gatewayPublicKey, response.signedPayload, response.signature)) throw new Error("Gateway identity could not be verified");
|
|
6242
|
+
const responseProof = decodeJson(response.signedPayload);
|
|
6243
|
+
if (responseProof.purpose !== "device-refresh-v3" || responseProof.gatewayId !== gateway.gatewayId || responseProof.requestId !== requestId || responseProof.nonce !== nonce || !(responseProof.expiresAt > Date.now()) || responseProof.expiresAt > Date.now() + 6e4) throw new Error("Gateway refresh response does not match this request");
|
|
6244
|
+
const payload = responseProof.tokens;
|
|
6245
|
+
if (!payload?.accessToken || !payload.accessTokenExpiresAt || payload.refreshToken !== nextRefreshToken) {
|
|
6211
6246
|
throw new Error("Gateway returned invalid browser credentials");
|
|
6212
6247
|
}
|
|
6213
|
-
return
|
|
6248
|
+
return payload;
|
|
6214
6249
|
}
|
|
6215
6250
|
function wait(milliseconds) {
|
|
6216
6251
|
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
6217
6252
|
}
|
|
6218
6253
|
async function pairGateway(link, onApproval) {
|
|
6219
|
-
const payload =
|
|
6220
|
-
const origin = new URL(payload.routes[0].url).origin;
|
|
6221
|
-
await requestGatewayOriginPermission(origin);
|
|
6254
|
+
const payload = parseBrowserPairingLink(link);
|
|
6222
6255
|
const pair = await getOrCreateKeyPair();
|
|
6223
6256
|
const requestId = crypto.randomUUID();
|
|
6224
6257
|
const initialRefreshToken = createRefreshToken();
|
|
6225
|
-
let
|
|
6258
|
+
let origin;
|
|
6259
|
+
let result;
|
|
6260
|
+
let lastRouteError;
|
|
6261
|
+
for (const candidate of [...new Set(payload.routes.map((route) => new URL(route.url).origin))]) {
|
|
6262
|
+
await requestGatewayOriginPermission(candidate);
|
|
6263
|
+
try {
|
|
6264
|
+
result = await signedPairingRequest(pair, payload, candidate, requestId, "request");
|
|
6265
|
+
origin = candidate;
|
|
6266
|
+
break;
|
|
6267
|
+
} catch (cause) {
|
|
6268
|
+
if (cause instanceof GatewayHttpError && cause.status < 500 && ![404, 408, 425, 429].includes(cause.status)) {
|
|
6269
|
+
throw cause;
|
|
6270
|
+
}
|
|
6271
|
+
lastRouteError = cause;
|
|
6272
|
+
}
|
|
6273
|
+
}
|
|
6274
|
+
if (!origin || !result) {
|
|
6275
|
+
throw lastRouteError instanceof Error ? lastRouteError : new Error("No Gateway route could be reached");
|
|
6276
|
+
}
|
|
6226
6277
|
if (result.request.status === "pending") onApproval(result.request.confirmationCode);
|
|
6227
6278
|
while (result.request.status === "pending") {
|
|
6228
6279
|
await wait(1500);
|
|
@@ -6238,7 +6289,7 @@ async function pairGateway(link, onApproval) {
|
|
|
6238
6289
|
});
|
|
6239
6290
|
}
|
|
6240
6291
|
if (!result.request.deviceId) throw new Error("Gateway did not register the browser");
|
|
6241
|
-
const tokens = await refreshAccessToken(origin, initialRefreshToken, pair);
|
|
6292
|
+
const tokens = await refreshAccessToken(origin, initialRefreshToken, pair, payload);
|
|
6242
6293
|
const profile = {
|
|
6243
6294
|
gatewayId: payload.gatewayId,
|
|
6244
6295
|
gatewayName: result.gateway.name,
|
|
@@ -6263,7 +6314,7 @@ async function getAccessProfile() {
|
|
|
6263
6314
|
if (profile.accessTokenExpiresAt > Date.now() + 3e4) return profile;
|
|
6264
6315
|
if (refreshTask) return refreshTask;
|
|
6265
6316
|
refreshTask = (async () => {
|
|
6266
|
-
const tokens = await refreshAccessToken(profile.gatewayUrl, profile.refreshToken, await getOrCreateKeyPair());
|
|
6317
|
+
const tokens = await refreshAccessToken(profile.gatewayUrl, profile.refreshToken, await getOrCreateKeyPair(), profile);
|
|
6267
6318
|
const next = { ...profile, ...tokens };
|
|
6268
6319
|
await chrome.storage.local.set({ [PROFILE_KEY]: next });
|
|
6269
6320
|
return next;
|
|
@@ -6352,4 +6403,4 @@ async function revokeAndForgetProfile() {
|
|
|
6352
6403
|
}
|
|
6353
6404
|
}
|
|
6354
6405
|
|
|
6355
|
-
export { ENDPOINT_PROTOCOL_VERSION as E, PENDING_CONTEXT_KEY as P, RealtimeClient as R, TAB_BINDING_PREFIX as T,
|
|
6406
|
+
export { ENDPOINT_PROTOCOL_VERSION as E, PENDING_CONTEXT_KEY as P, RealtimeClient as R, TAB_BINDING_PREFIX as T, PENDING_PAIRING_LINK_KEY as a, activeTabId as b, canonicalJson as c, captureTabWithPermission as d, createBrowserEndpointHello as e, currentTabDescriptor as f, deleteBrowserOutbox as g, discoverLocalGateway as h, endpointToolContentSchema as i, gatewayFetch as j, getAccessProfile as k, parseBrowserPairingLink as l, readProfile as m, registerBrowserEndpoint as n, revokeAndForgetProfile as o, pairGateway as p, runWithTabSiteAccess as q, readBrowserOutbox as r, setAutoConnectEnabled as s, takePendingPairingLink as t, writeBrowserOutbox as w };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as endpointToolContentSchema, E as ENDPOINT_PROTOCOL_VERSION, c as canonicalJson, T as TAB_BINDING_PREFIX, d as captureTabWithPermission, P as PENDING_CONTEXT_KEY, l as parseBrowserPairingLink, a as PENDING_PAIRING_LINK_KEY, m as readProfile, n as registerBrowserEndpoint, k as getAccessProfile, R as RealtimeClient, e as createBrowserEndpointHello, j as gatewayFetch } from './assets/auth-C1QI-uMG.js';
|
|
2
2
|
|
|
3
3
|
const BROWSER_EXTENSION_PROTOCOL_VERSION = 4;
|
|
4
4
|
const BROWSER_CONTROL_ENDPOINT_TOOL_NAME = "browser.control";
|
|
@@ -1253,7 +1253,23 @@ function connectWithLogging() {
|
|
|
1253
1253
|
if (generation !== connectionGeneration && !realtime) connectWithLogging();
|
|
1254
1254
|
});
|
|
1255
1255
|
}
|
|
1256
|
-
|
|
1256
|
+
async function stagePairingInvite(message, sender) {
|
|
1257
|
+
if (typeof message.pairingLink !== "string" || !sender.url || !sender.tab?.id) {
|
|
1258
|
+
throw new Error("Pairing handoff is missing its source tab");
|
|
1259
|
+
}
|
|
1260
|
+
const source = new URL(sender.url);
|
|
1261
|
+
const invitation = new URL(message.pairingLink);
|
|
1262
|
+
if (source.href !== invitation.href || source.protocol !== "https:" || source.hostname !== "link.xopc.ai" || source.pathname !== "/connect") {
|
|
1263
|
+
throw new Error("Pairing handoff source is not trusted");
|
|
1264
|
+
}
|
|
1265
|
+
parseBrowserPairingLink(invitation.href);
|
|
1266
|
+
const tasks = [
|
|
1267
|
+
chrome.storage.session.set({ [PENDING_PAIRING_LINK_KEY]: invitation.href })
|
|
1268
|
+
];
|
|
1269
|
+
if (message.open) tasks.push(chrome.sidePanel.open({ tabId: sender.tab.id }));
|
|
1270
|
+
await Promise.all(tasks);
|
|
1271
|
+
}
|
|
1272
|
+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
1257
1273
|
if (message.type === "browser/get-status") {
|
|
1258
1274
|
sendResponse({ connected: Boolean(endpointClaim), transport: "gateway-realtime", error: lastConnectionError });
|
|
1259
1275
|
} else if (message.type === "browser/get-endpoint-claim") {
|
|
@@ -1262,6 +1278,11 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
|
|
1262
1278
|
disconnect();
|
|
1263
1279
|
connectWithLogging();
|
|
1264
1280
|
sendResponse({ ok: true });
|
|
1281
|
+
} else if (message.type === "browser/stage-pairing-invite") {
|
|
1282
|
+
void stagePairingInvite(message, sender).then(() => sendResponse({ ok: true })).catch((cause) => sendResponse({
|
|
1283
|
+
ok: false,
|
|
1284
|
+
error: cause instanceof Error ? cause.message : String(cause)
|
|
1285
|
+
}));
|
|
1265
1286
|
} else {
|
|
1266
1287
|
sendResponse({ ok: false, error: `Unknown message: ${message.type}` });
|
|
1267
1288
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const messageType = "browser/stage-pairing-invite";
|
|
2
|
+
function hasPairingPayload() {
|
|
3
|
+
return new URLSearchParams(location.hash.slice(1)).has("p");
|
|
4
|
+
}
|
|
5
|
+
async function stage(open) {
|
|
6
|
+
return chrome.runtime.sendMessage({
|
|
7
|
+
type: messageType,
|
|
8
|
+
pairingLink: location.href,
|
|
9
|
+
open
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function mountOpenButton() {
|
|
13
|
+
if (document.getElementById("xopc-browser-pairing-handoff")) return;
|
|
14
|
+
const host = document.createElement("div");
|
|
15
|
+
host.id = "xopc-browser-pairing-handoff";
|
|
16
|
+
const root = host.attachShadow({ mode: "closed" });
|
|
17
|
+
const button = document.createElement("button");
|
|
18
|
+
button.type = "button";
|
|
19
|
+
button.textContent = "Open xopc extension";
|
|
20
|
+
button.style.cssText = [
|
|
21
|
+
"position:fixed",
|
|
22
|
+
"right:24px",
|
|
23
|
+
"bottom:24px",
|
|
24
|
+
"z-index:2147483647",
|
|
25
|
+
"border:0",
|
|
26
|
+
"border-radius:10px",
|
|
27
|
+
"padding:12px 18px",
|
|
28
|
+
"background:#2563eb",
|
|
29
|
+
"color:#fff",
|
|
30
|
+
"font:600 14px/20px system-ui,sans-serif",
|
|
31
|
+
"box-shadow:0 8px 24px rgba(15,23,42,.24)",
|
|
32
|
+
"cursor:pointer"
|
|
33
|
+
].join(";");
|
|
34
|
+
button.addEventListener("click", () => {
|
|
35
|
+
button.disabled = true;
|
|
36
|
+
button.textContent = "Opening…";
|
|
37
|
+
void stage(true).then((result) => {
|
|
38
|
+
button.textContent = result.ok ? "Opened — approve in Gateway" : result.error || "Could not open xopc";
|
|
39
|
+
button.disabled = false;
|
|
40
|
+
}).catch(() => {
|
|
41
|
+
button.textContent = "Could not open xopc";
|
|
42
|
+
button.disabled = false;
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
root.append(button);
|
|
46
|
+
document.documentElement.append(host);
|
|
47
|
+
}
|
|
48
|
+
if (hasPairingPayload()) {
|
|
49
|
+
void stage(false).catch(() => void 0);
|
|
50
|
+
mountOpenButton();
|
|
51
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>xopc</title>
|
|
7
7
|
<script type="module" crossorigin src="./sidepanel.js"></script>
|
|
8
|
-
<link rel="modulepreload" crossorigin href="./assets/auth-
|
|
8
|
+
<link rel="modulepreload" crossorigin href="./assets/auth-C1QI-uMG.js">
|
|
9
9
|
<link rel="stylesheet" crossorigin href="./assets/sidepanel-C86O7q5Y.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as RealtimeClient,
|
|
1
|
+
import { R as RealtimeClient, j as gatewayFetch, b as activeTabId, r as readBrowserOutbox, w as writeBrowserOutbox, g as deleteBrowserOutbox, f as currentTabDescriptor, T as TAB_BINDING_PREFIX, k as getAccessProfile, q as runWithTabSiteAccess, P as PENDING_CONTEXT_KEY, d as captureTabWithPermission, p as pairGateway, s as setAutoConnectEnabled, t as takePendingPairingLink, m as readProfile, h as discoverLocalGateway, a as PENDING_PAIRING_LINK_KEY, o as revokeAndForgetProfile } from './assets/auth-C1QI-uMG.js';
|
|
2
2
|
|
|
3
3
|
true &&(function polyfill() {
|
|
4
4
|
const relList = document.createElement("link").relList;
|
|
@@ -27552,10 +27552,35 @@ function SidePanelApp() {
|
|
|
27552
27552
|
const [error, setError] = reactExports.useState("");
|
|
27553
27553
|
const [localPairingLink, setLocalPairingLink] = reactExports.useState("");
|
|
27554
27554
|
const initializationStarted = reactExports.useRef(false);
|
|
27555
|
+
const pairingStarted = reactExports.useRef(false);
|
|
27556
|
+
const connect = reactExports.useCallback(async (link) => {
|
|
27557
|
+
if (pairingStarted.current) return;
|
|
27558
|
+
pairingStarted.current = true;
|
|
27559
|
+
setState("pairing");
|
|
27560
|
+
setError("");
|
|
27561
|
+
setPairingLink(link);
|
|
27562
|
+
try {
|
|
27563
|
+
const paired = await pairGateway(link, setConfirmationCode);
|
|
27564
|
+
await setAutoConnectEnabled(true);
|
|
27565
|
+
await reconnectBrowserBridge();
|
|
27566
|
+
setProfile(paired);
|
|
27567
|
+
setState("online");
|
|
27568
|
+
} catch (cause) {
|
|
27569
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
27570
|
+
setState("unpaired");
|
|
27571
|
+
} finally {
|
|
27572
|
+
pairingStarted.current = false;
|
|
27573
|
+
}
|
|
27574
|
+
}, []);
|
|
27555
27575
|
reactExports.useEffect(() => {
|
|
27556
27576
|
if (initializationStarted.current) return;
|
|
27557
27577
|
initializationStarted.current = true;
|
|
27558
27578
|
void (async () => {
|
|
27579
|
+
const handedOff = await takePendingPairingLink();
|
|
27580
|
+
if (handedOff) {
|
|
27581
|
+
await connect(handedOff);
|
|
27582
|
+
return;
|
|
27583
|
+
}
|
|
27559
27584
|
const stored = await readProfile();
|
|
27560
27585
|
if (stored) {
|
|
27561
27586
|
await reconnectBrowserBridge();
|
|
@@ -27569,33 +27594,20 @@ function SidePanelApp() {
|
|
|
27569
27594
|
return;
|
|
27570
27595
|
}
|
|
27571
27596
|
setLocalPairingLink(local.pairingLink);
|
|
27572
|
-
|
|
27573
|
-
try {
|
|
27574
|
-
const paired = await pairGateway(local.pairingLink, setConfirmationCode);
|
|
27575
|
-
await reconnectBrowserBridge();
|
|
27576
|
-
setProfile(paired);
|
|
27577
|
-
setState("online");
|
|
27578
|
-
} catch (cause) {
|
|
27579
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
27580
|
-
setState("unpaired");
|
|
27581
|
-
}
|
|
27597
|
+
await connect(local.pairingLink);
|
|
27582
27598
|
})();
|
|
27583
|
-
}, []);
|
|
27599
|
+
}, [connect]);
|
|
27600
|
+
reactExports.useEffect(() => {
|
|
27601
|
+
const handleStorageChange = (changes, area) => {
|
|
27602
|
+
if (area !== "session" || !changes[PENDING_PAIRING_LINK_KEY]?.newValue) return;
|
|
27603
|
+
void takePendingPairingLink().then((link) => {
|
|
27604
|
+
if (link) void connect(link);
|
|
27605
|
+
});
|
|
27606
|
+
};
|
|
27607
|
+
chrome.storage.onChanged.addListener(handleStorageChange);
|
|
27608
|
+
return () => chrome.storage.onChanged.removeListener(handleStorageChange);
|
|
27609
|
+
}, [connect]);
|
|
27584
27610
|
reactExports.useEffect(() => watchSidePanelTheme(profile?.gatewayUrl), [profile?.gatewayUrl]);
|
|
27585
|
-
async function connect(link = pairingLink) {
|
|
27586
|
-
setState("pairing");
|
|
27587
|
-
setError("");
|
|
27588
|
-
try {
|
|
27589
|
-
const paired = await pairGateway(link, setConfirmationCode);
|
|
27590
|
-
await setAutoConnectEnabled(true);
|
|
27591
|
-
await reconnectBrowserBridge();
|
|
27592
|
-
setProfile(paired);
|
|
27593
|
-
setState("online");
|
|
27594
|
-
} catch (cause) {
|
|
27595
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
27596
|
-
setState("unpaired");
|
|
27597
|
-
}
|
|
27598
|
-
}
|
|
27599
27611
|
async function disconnect() {
|
|
27600
27612
|
await revokeAndForgetProfile();
|
|
27601
27613
|
setProfile(void 0);
|
|
@@ -27648,7 +27660,7 @@ function SidePanelApp() {
|
|
|
27648
27660
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "approval-code", children: confirmationCode })
|
|
27649
27661
|
] }) : null,
|
|
27650
27662
|
error ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "error-text", children: error }) : null,
|
|
27651
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "actions", children: /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary", onClick: () => void connect(), disabled: !pairingLink.trim() || state === "pairing", children: state === "pairing" ? "Waiting for approval…" : "Connect" }) })
|
|
27663
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "actions", children: /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary", onClick: () => void connect(pairingLink), disabled: !pairingLink.trim() || state === "pairing", children: state === "pairing" ? "Waiting for approval…" : "Connect" }) })
|
|
27652
27664
|
] }) : null
|
|
27653
27665
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChatPanel, {}),
|
|
27654
27666
|
state === "online" && profile ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "disconnect-link", onClick: disconnect, title: `Disconnect ${profile.gatewayName}`, children: "Disconnect" }) : null
|
|
@@ -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.272",
|
|
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": [
|
|
@@ -28,6 +28,17 @@
|
|
|
28
28
|
"service_worker": "dist/background.js",
|
|
29
29
|
"type": "module"
|
|
30
30
|
},
|
|
31
|
+
"content_scripts": [
|
|
32
|
+
{
|
|
33
|
+
"matches": [
|
|
34
|
+
"https://link.xopc.ai/connect*"
|
|
35
|
+
],
|
|
36
|
+
"js": [
|
|
37
|
+
"dist/pairing-handoff.js"
|
|
38
|
+
],
|
|
39
|
+
"run_at": "document_idle"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
31
42
|
"side_panel": {
|
|
32
43
|
"default_path": "dist/sidepanel.html"
|
|
33
44
|
},
|
|
@@ -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.272",
|
|
6
6
|
"kind": "channel",
|
|
7
7
|
"main": "src/index.js",
|
|
8
8
|
"channels": [
|
package/dist/gateway/static/root/assets/{activity-store-D_0FmdRj.js → activity-store-DffqjeqQ.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{p as e}from"./locale-store-CRNble2Z.js";var t=`xopc.activity-center.v1`,n=80,r=720*60*60*1e3;function i(e){return e===`error`?`failed`:e===`warning`?`attention`:`done`}function a(){if(!(typeof window>`u`))return window.location.hash.replace(/^#/,``)||`${window.location.pathname}${window.location.search}`||void 0}function o(){try{let e=globalThis.localStorage?.getItem(t);if(!e)return[];let i=JSON.parse(e);if(!Array.isArray(i.items))return[];let a=Date.now()-r,o=i.items.filter(e=>e&&typeof e.id==`string`&&typeof e.title==`string`).filter(e=>Number.isFinite(e.updatedAt)&&e.updatedAt>=a).slice(0,n);return o.length!==i.items.length&&s(o),o}catch{return[]}}function s(e){try{globalThis.localStorage?.setItem(t,JSON.stringify({items:e}))}catch{}}function c(e){return`${e.toString(36)}-${Math.random().toString(36).slice(2,8)}`}var l=e(e=>({items:o(),add:t=>e(e=>{let r=t.title.trim();if(!r)return e;let o=Date.now(),l=t.tone??`info`,u=t.dedupeKey?e.items.findIndex(e=>e.dedupeKey===t.dedupeKey):-1,d=[{id:u>=0?e.items[u].id:c(o),tone:l,status:t.status??i(l),title:r,message:t.message?.trim()||void 0,source:t.source?.trim()||void 0,href:t.href??a(),dedupeKey:t.dedupeKey,createdAt:u>=0?e.items[u].createdAt:o,updatedAt:o,read:t.read??!1,occurrences:u>=0?e.items[u].occurrences+1:1},...u>=0?e.items.filter((e,t)=>t!==u):e.items].slice(0,n);return s(d),{items:d}}),markAllRead:()=>e(e=>{let t=e.items.map(e=>({...e,read:!0}));return s(t),{items:t}}),remove:t=>e(e=>{let n=e.items.filter(e=>e.id!==t);return s(n),{items:n}}),clearFinished:()=>e(e=>{let t=e.items.filter(e=>e.status!==`done`);return s(t),{items:t}}),clear:()=>{s([]),e({items:[]})}}));function u(e){l.getState().add(e)}export{u as t};
|