@xopcai/xopc 0.0.269 → 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-DcwCSY6s.js → activity-store-DffqjeqQ.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D0NBOWC4.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-eaPO-mdr.js → api-CGLdye4i.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-E3xm2teY.js → app-management-settings-panel-BLujSbaw.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CiZOjgls.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-D09yo_Hc.js → archive-plugin-D4bUampf.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CNYb8Qru.js → attachment-load-CBGNA2Ys.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DsrfW5ii.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-OWlaGqlY.js → binary-plugins-bbvp81h2.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CVND3M6r.js → block-editor-C8e6Wri4.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-D7IzVK_J.js → browser-automation-inputs-oJWJtQa6.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-CQ6cCpIv.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-D4JrgJKa.js → channels-status-swr-CfOPNnVr.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BUjnhT7C.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-Z6Nf0Wjq.js → dependency-picker-D1q89tVc.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-C0F5Iqnc.js → desktop-pet-DfqZBvhp.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Bj_W6HL1.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-Ba09EnAn.js → extension-debug-page-C8cAWVoK.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C88aGXJs.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-bjzk_4hn.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-DrbIzFyB.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-CBWU9Ner.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-B8Z7kKQY.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-CLSfzkRp.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-DIcfrLmG.js → markdown-view-AglreSOj.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CSv6-xTA.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-BRjoarIr.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-BfV-PQa5.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-DQS7NFpg.js → preview-open-alternatives-iknB5xEp.js} +1 -1
- package/dist/gateway/static/root/assets/proactive-card-BPZDgNNR.js +1 -0
- package/dist/gateway/static/root/assets/proactive-page-CxdZR-p2.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-BIhjZLKg.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-CwveUfe8.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-DMQ0wpNg.js → runtime-tools-settings-panel-DP1XyYO8.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-C91g2PRU.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-Cem6L49Y.js → settings-form-section-2LGjz7bu.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-afDUxqlV.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-CVEVHksg.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-CNrq1W6C.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-BLE8PxWE.js → system-settings-panel-8NIssGKj.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-L6dp9v2y.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-BejLVjIT.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-DmgEA8Qb.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-sZ0J83SF.js → voice-api-key-field-Bd03Ic0s.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-BEbz3avx.js → voice-config-api-gggUp3u9.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BXnAlbmO.js → work-discovery-overlay-DF8PR_pK.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BkwFey0a.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/notifications.js +2 -2
- package/dist/packages/gateway-contract/src/proactive.js +22 -6
- 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/agent/tool-manuals/xopc-use.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js +19 -1
- package/dist/src/agent/tools/factory.js +1 -0
- package/dist/src/agent/tools/xopc-use-tool.d.ts +3 -2
- package/dist/src/agent/tools/xopc-use-tool.js +48 -4
- package/dist/src/browser/automations/schema.d.ts +1 -1
- package/dist/src/browser/automations/service.d.ts +1 -1
- package/dist/src/browser/native-messaging-host.js +3 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/tunnel.js +5 -0
- package/dist/src/connectors/connected-source-ingestion.js +1 -1
- package/dist/src/connectors/connected-source-normalizers.js +3 -0
- package/dist/src/connectors/connection-recovery-service.js +1 -1
- package/dist/src/connectors/health.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/capabilities.js +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +1 -1
- 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/mcp.js +1 -1
- 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/proactive-control.js +31 -24
- 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/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/service.d.ts +1 -0
- package/dist/src/gateway/service.js +21 -11
- 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/notifications/web-push.js +1 -1
- package/dist/src/proactive/actions/service.js +4 -2
- package/dist/src/proactive/execution/authorization.d.ts +2 -0
- package/dist/src/proactive/execution/authorization.js +39 -1
- package/dist/src/proactive/execution/context.d.ts +4 -0
- package/dist/src/proactive/execution/context.js +51 -5
- package/dist/src/proactive/execution/insight.js +3 -1
- package/dist/src/proactive/execution/repository.js +15 -5
- package/dist/src/proactive/execution/types.d.ts +2 -0
- package/dist/src/proactive/execution/worker.js +7 -2
- package/dist/src/proactive/experience.d.ts +69 -0
- package/dist/src/proactive/experience.js +90 -0
- package/dist/src/proactive/follow-ups.d.ts +123 -0
- package/dist/src/proactive/follow-ups.js +169 -0
- package/dist/src/proactive/inbox/cards.js +35 -6
- package/dist/src/proactive/inbox/delivery.js +4 -2
- package/dist/src/proactive/inbox/digest.js +2 -2
- package/dist/src/proactive/inbox/lifecycle.js +4 -1
- package/dist/src/proactive/inbox/notification-policy.js +4 -2
- package/dist/src/proactive/inbox/repository.js +17 -11
- package/dist/src/proactive/inbox/types.d.ts +2 -0
- package/dist/src/proactive/inbox/worker.js +1 -1
- package/dist/src/proactive/index.js +2 -2
- package/dist/src/proactive/mail-thread.d.ts +13 -0
- package/dist/src/proactive/mail-thread.js +54 -0
- package/dist/src/proactive/policy/service.d.ts +3 -5
- package/dist/src/proactive/policy/service.js +3 -5
- package/dist/src/proactive/scenarios/control.d.ts +4 -7
- package/dist/src/proactive/scenarios/control.js +3 -4
- package/dist/src/proactive/scenarios/preview.js +1 -1
- package/dist/src/proactive/scenarios/prompt-composer.js +2 -0
- package/dist/src/proactive/service.js +1 -1
- package/dist/src/proactive/temporal/worker.d.ts +1 -0
- package/dist/src/proactive/temporal/worker.js +18 -4
- 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/162_proactive_product.sql +7 -0
- package/dist/src/storage/sqlite/migrations/163_proactive_follow_ups.sql +29 -0
- 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/tasks/home-query-service.js +1 -1
- package/dist/src/tasks/index.js +4 -4
- package/dist/src/tui/tui-startup-resources.js +1 -1
- 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/dashscope/streaming-stt-session.js +1 -0
- package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +1 -0
- package/dist/src/voice/dashscope/streaming-tts-stream.js +8 -0
- package/dist/src/voice/realtime/agentBroker.js +1 -1
- package/dist/src/voice/realtime/agentEngine.js +1 -1
- package/dist/src/voice/realtime/pcm-output-gain.d.ts +2 -0
- package/dist/src/voice/realtime/pcm-output-gain.js +16 -0
- package/dist/src/voice/realtime/runtime.d.ts +1 -0
- package/dist/src/voice/realtime/runtime.js +21 -3
- package/dist/src/voice/realtime/runtime.types.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +3 -1
- 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-qKCezlBg.js +0 -1
- package/dist/gateway/static/root/assets/agents-BMhnZKhP.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-DduJDWGY.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-X7hNHCjW.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-BZ7nK_pN.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BfKvJO1C.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-D1UDxJuA.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-C2nuqs_O.js +0 -2
- package/dist/gateway/static/root/assets/cron-expression-DlyRIyUn.js +0 -2
- package/dist/gateway/static/root/assets/date-picker-CU-ij_yE.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CMyt0A32.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-ogv8ZbvG.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-BnrMRKaZ.js +0 -1
- package/dist/gateway/static/root/assets/home-page-CbcJCREd.js +0 -1
- package/dist/gateway/static/root/assets/index-7PZ6jmhy.css +0 -2
- package/dist/gateway/static/root/assets/index-CfyyA9-g.js +0 -74
- package/dist/gateway/static/root/assets/local-app-workbench-page-D5XVZnK1.js +0 -2
- package/dist/gateway/static/root/assets/locale-store-BQ2HKTWb.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-CWDU1AGN.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-CuFNgQUy.js +0 -1
- package/dist/gateway/static/root/assets/mobile-pairing-wizard-C7d_ztgp.js +0 -1
- package/dist/gateway/static/root/assets/note-detail-panel-D5JuBLyt.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-C5-ccCi4.js +0 -8
- package/dist/gateway/static/root/assets/popover-select-CKBYnT3c.js +0 -1
- package/dist/gateway/static/root/assets/proactive-page-fHjPigmx.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-6v_khvEt.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CCy1aK4V.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-pkqKRnch.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-Cr4E4cap.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-D1JRDRyL.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Cc_iP_vv.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BrMECMAB.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DuqIDYjc.js +0 -1
- package/dist/gateway/static/root/assets/skills-page.utils-D1wGfm22.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-m0oXUKl2.js +0 -1
- package/dist/gateway/static/root/assets/tunnel-api-Dur80zSQ.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-Dl10D_5q.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-CswgoIFU.js +0 -6
- package/dist/src/proactive/actions/workflow.d.ts +0 -15
- package/dist/src/proactive/actions/workflow.js +0 -88
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SESSION_SOURCE_CHANNELS } from "../../../packages/gateway-contract/src/session-identity.js";
|
|
2
|
+
//#region src/storage/sqlite/session-identity-sql.ts
|
|
3
|
+
const custom = (key) => `json_extract(CASE WHEN json_valid(s.custom_data_json) THEN s.custom_data_json ELSE '{}' END, '$.${key}')`;
|
|
4
|
+
const channel = "LOWER(TRIM(s.source_channel))";
|
|
5
|
+
const SESSION_SOURCE_SQL = `(CASE
|
|
6
|
+
WHEN s.session_type = 'heartbeat' THEN 'system'
|
|
7
|
+
WHEN ${custom("origin")} = 'automation' OR ${custom("triggerSource")} = 'automation' OR s.session_type = 'cron' THEN 'automation'
|
|
8
|
+
WHEN ${custom("createdSurface")} = 'browser_extension' THEN 'browser'
|
|
9
|
+
${Object.entries(SESSION_SOURCE_CHANNELS).map(([name, aliases]) => `WHEN ${channel} IN (${aliases.map((alias) => `'${alias}'`).join(",")}) THEN '${name}'`).join("\n ")}
|
|
10
|
+
ELSE 'other' END)`;
|
|
11
|
+
const SESSION_PURPOSE_SQL = `(CASE
|
|
12
|
+
WHEN ${SESSION_SOURCE_SQL} = 'system' THEN 'system'
|
|
13
|
+
WHEN s.session_type = 'workflow-subagent' THEN 'subagent'
|
|
14
|
+
WHEN s.session_type = 'workflow-run' THEN 'workflow'
|
|
15
|
+
WHEN ${SESSION_SOURCE_SQL} = 'automation' THEN 'automation'
|
|
16
|
+
ELSE 'chat' END)`;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { SESSION_PURPOSE_SQL, SESSION_SOURCE_SQL };
|
|
@@ -5,6 +5,7 @@ import { buildGlobalSessionStats, metadataToSessionInsert, sessionRowToMetadata
|
|
|
5
5
|
import { cancelConnectionObjective } from "./connection-wait-repository.js";
|
|
6
6
|
import { notifyUserContextChange } from "../../user-context/changes.js";
|
|
7
7
|
import { validateSessionId } from "../../session/session-id.js";
|
|
8
|
+
import { SESSION_PURPOSE_SQL, SESSION_SOURCE_SQL } from "./session-identity-sql.js";
|
|
8
9
|
import { buildFts5SearchQuery } from "./fts.js";
|
|
9
10
|
import { randomUUID } from "node:crypto";
|
|
10
11
|
//#region src/storage/sqlite/session-repository.ts
|
|
@@ -81,7 +82,7 @@ function listSessionMetadata(query = {}) {
|
|
|
81
82
|
if (query.sessionTypes?.length) {
|
|
82
83
|
conditions.push(`s.session_type IN (${query.sessionTypes.map(() => "?").join(", ")})`);
|
|
83
84
|
params.push(...query.sessionTypes);
|
|
84
|
-
} else if (!query.includeHidden) {
|
|
85
|
+
} else if (!query.includeHidden && !query.purposes?.length && !query.activity && !query.sources?.length) {
|
|
85
86
|
conditions.push(`s.session_type = ?`);
|
|
86
87
|
params.push("chat");
|
|
87
88
|
}
|
|
@@ -90,6 +91,21 @@ function listSessionMetadata(query = {}) {
|
|
|
90
91
|
conditions.push(`s.status IN (${statuses.map(() => "?").join(", ")})`);
|
|
91
92
|
params.push(...statuses);
|
|
92
93
|
}
|
|
94
|
+
if (query.excludeArchived) conditions.push(`s.status != 'archived'`);
|
|
95
|
+
if (query.sources?.length) {
|
|
96
|
+
conditions.push(`${SESSION_SOURCE_SQL} IN (${query.sources.map(() => "?").join(",")})`);
|
|
97
|
+
params.push(...query.sources);
|
|
98
|
+
}
|
|
99
|
+
if (query.purposes?.length) {
|
|
100
|
+
conditions.push(`${SESSION_PURPOSE_SQL} IN (${query.purposes.map(() => "?").join(",")})`);
|
|
101
|
+
params.push(...query.purposes);
|
|
102
|
+
}
|
|
103
|
+
if (query.activity === "automatic") conditions.push(`${SESSION_SOURCE_SQL} IN ('automation', 'system')`);
|
|
104
|
+
if (query.activity === "manual") conditions.push(`${SESSION_PURPOSE_SQL} = 'chat' AND ${SESSION_SOURCE_SQL} NOT IN ('automation', 'system')`);
|
|
105
|
+
if (query.agentId) {
|
|
106
|
+
conditions.push("s.agent_id = ?");
|
|
107
|
+
params.push(query.agentId);
|
|
108
|
+
}
|
|
93
109
|
if (query.projectId) {
|
|
94
110
|
conditions.push(`s.project_id = ?`);
|
|
95
111
|
params.push(query.projectId);
|
|
@@ -126,29 +142,17 @@ function listSessionMetadata(query = {}) {
|
|
|
126
142
|
conditions.push(`s.tags_json LIKE ?`);
|
|
127
143
|
params.push(`%"${tag}"%`);
|
|
128
144
|
}
|
|
129
|
-
let searchKeys = null;
|
|
130
145
|
if (query.search?.trim()) {
|
|
131
146
|
const rawSearch = query.search.trim();
|
|
132
|
-
const ftsQuery = buildFts5SearchQuery(rawSearch);
|
|
133
|
-
const ftsRows = db.prepare(`SELECT DISTINCT session_key FROM transcript_fts WHERE transcript_fts MATCH ? LIMIT 500`).all(ftsQuery);
|
|
134
|
-
const ftsKeys = new Set(ftsRows.map((r) => r.session_key));
|
|
135
147
|
const like = `%${rawSearch.toLowerCase()}%`;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
items: [],
|
|
145
|
-
total: 0,
|
|
146
|
-
limit: query.limit ?? 50,
|
|
147
|
-
offset: query.offset ?? 0,
|
|
148
|
-
hasMore: false
|
|
149
|
-
};
|
|
150
|
-
conditions.push(`s.session_key IN (${searchKeys.map(() => "?").join(", ")})`);
|
|
151
|
-
params.push(...searchKeys);
|
|
148
|
+
conditions.push(`(s.session_key IN (
|
|
149
|
+
SELECT session_key FROM transcript_fts WHERE transcript_fts MATCH ?
|
|
150
|
+
) OR LOWER(s.session_key) LIKE ?
|
|
151
|
+
OR LOWER(COALESCE(s.name, '')) LIKE ?
|
|
152
|
+
OR LOWER(s.source_channel) LIKE ?
|
|
153
|
+
OR LOWER(s.source_chat_id) LIKE ?
|
|
154
|
+
OR LOWER(s.tags_json) LIKE ?)`);
|
|
155
|
+
params.push(buildFts5SearchQuery(rawSearch), like, like, like, like, like);
|
|
152
156
|
}
|
|
153
157
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
154
158
|
const sortColumn = sessionSortColumn(query.sortBy);
|
|
@@ -158,7 +162,7 @@ function listSessionMetadata(query = {}) {
|
|
|
158
162
|
const offset = query.offset ?? 0;
|
|
159
163
|
return {
|
|
160
164
|
items: db.prepare(`SELECT ${SESSION_COLUMNS} ${SESSION_FROM_JOIN} ${where}
|
|
161
|
-
ORDER BY ${sortColumn} ${sortOrder}
|
|
165
|
+
ORDER BY ${sortColumn} ${sortOrder}, s.session_key ASC
|
|
162
166
|
LIMIT ? OFFSET ?`).all(...params, limit, offset).map((row) => sessionRowToMetadata(row.session_key, row)),
|
|
163
167
|
total,
|
|
164
168
|
limit,
|
|
@@ -336,7 +336,7 @@ var HomeQueryService = class {
|
|
|
336
336
|
detail: item.insight.summary,
|
|
337
337
|
reason: item.insight.disposition === "request_approval" ? "approval_required" : item.insight.attentionKind === "decision" ? "decision_needed" : "insight_available",
|
|
338
338
|
urgency: item.insight.urgency === "critical" || item.insight.urgency === "high" ? "now" : "soon",
|
|
339
|
-
href:
|
|
339
|
+
href: `/assistant-work?item=${encodeURIComponent(item.id)}`,
|
|
340
340
|
updatedAt: Date.parse(item.updatedAt),
|
|
341
341
|
judgment: {
|
|
342
342
|
inboxItemId: item.id,
|
package/dist/src/tasks/index.js
CHANGED
|
@@ -3,18 +3,18 @@ import { TaskRunRepository } from "./task-run-repository.js";
|
|
|
3
3
|
import { TaskRepository } from "./task-repository.js";
|
|
4
4
|
import { TaskConversationConflictError, TaskConversationRepository } from "./task-conversation-repository.js";
|
|
5
5
|
import { TaskReadModelProjector } from "./task-read-model-projector.js";
|
|
6
|
-
import { resolveExecutionContext } from "./execution-context.js";
|
|
7
|
-
import { AttentionGovernor } from "./attention-governor.js";
|
|
8
|
-
import { HomeQueryService, buildHomeWorkbench, decisionFromTask } from "./home-query-service.js";
|
|
9
6
|
import { TaskContextRepository } from "./task-context-repository.js";
|
|
10
7
|
import { TaskDependencyError, TaskDependencyService } from "./task-dependency-service.js";
|
|
11
8
|
import { TaskApplicationService } from "./task-application-service.js";
|
|
9
|
+
import { ProjectMonitoringService, decideProactiveDisposition, isInQuietHours, nextQuietHoursEnd, proactiveDispositionReason } from "./project-monitoring-service.js";
|
|
10
|
+
import { resolveExecutionContext } from "./execution-context.js";
|
|
11
|
+
import { AttentionGovernor } from "./attention-governor.js";
|
|
12
|
+
import { HomeQueryService, buildHomeWorkbench, decisionFromTask } from "./home-query-service.js";
|
|
12
13
|
import { TaskWorkflowCoordinator } from "./task-workflow-coordinator.js";
|
|
13
14
|
import { defineTaskContract } from "./task-contract-definition.js";
|
|
14
15
|
import { ModelTaskContractPlanner, parseTaskContractResponse } from "./task-contract-planner.js";
|
|
15
16
|
import { assembleTaskContext, buildTaskExecutionDirective, getTaskContextManifest, getTaskExecutionBrief } from "./task-context-assembler.js";
|
|
16
17
|
import { TaskRunCoordinator } from "./task-run-coordinator.js";
|
|
17
|
-
import { ProjectMonitoringService, decideProactiveDisposition, isInQuietHours, nextQuietHoursEnd, proactiveDispositionReason } from "./project-monitoring-service.js";
|
|
18
18
|
import { ProjectOperatingViewService, summarizeProjectOperatingView } from "./project-operating-view-service.js";
|
|
19
19
|
import { TaskValueMetricsService } from "./task-value-metrics-service.js";
|
|
20
20
|
import { TaskHandoffService } from "./task-handoff-service.js";
|
|
@@ -5,9 +5,9 @@ import { resolveBootstrapFilesSync } from "../agent/bootstrap/bootstrap-files.js
|
|
|
5
5
|
import { createSkillConfigManager, isSkillEnabled } from "../agent/skills/config.js";
|
|
6
6
|
import { loadSkills } from "../agent/skills/index.js";
|
|
7
7
|
import { createWorkflowCatalog } from "../agent/workflow/catalog.js";
|
|
8
|
+
import { listConnectorInstances } from "../connectors/instances.js";
|
|
8
9
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
9
10
|
import "../config/index.js";
|
|
10
|
-
import { listConnectorInstances } from "../connectors/instances.js";
|
|
11
11
|
import { basename } from "node:path";
|
|
12
12
|
//#region src/tui/tui-startup-resources.ts
|
|
13
13
|
init_paths();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/tunnel/auth-policy.ts
|
|
2
|
+
/** A public FRP ingress cannot trust local sockets or proxy identity headers. */
|
|
3
|
+
function requireTunnelGatewayToken(auth) {
|
|
4
|
+
if (auth.mode !== "token" || !auth.token?.trim()) throw new Error("Public remote access requires gateway token authentication.");
|
|
5
|
+
return auth.token;
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { requireTunnelGatewayToken };
|
|
@@ -4,9 +4,13 @@ export type BrokerRegisterInput = {
|
|
|
4
4
|
registrationSecret: string;
|
|
5
5
|
gatewayVersion: string;
|
|
6
6
|
platform: string;
|
|
7
|
-
|
|
7
|
+
recoveryToken?: string;
|
|
8
8
|
preferredSubdomain?: string;
|
|
9
9
|
};
|
|
10
|
+
export declare class TunnelBrokerError extends Error {
|
|
11
|
+
readonly status: number;
|
|
12
|
+
constructor(status: number, message: string);
|
|
13
|
+
}
|
|
10
14
|
export declare class TunnelBrokerClient {
|
|
11
15
|
private readonly baseUrl;
|
|
12
16
|
constructor(baseUrl: string);
|
|
@@ -14,19 +18,5 @@ export declare class TunnelBrokerClient {
|
|
|
14
18
|
register(input: BrokerRegisterInput): Promise<TunnelRegistration>;
|
|
15
19
|
heartbeat(tunnelId: string, tunnelToken: string): Promise<void>;
|
|
16
20
|
deregister(tunnelId: string, tunnelToken: string): Promise<void>;
|
|
17
|
-
setDnsChallenge(input: {
|
|
18
|
-
tunnelId: string;
|
|
19
|
-
tunnelToken: string;
|
|
20
|
-
subdomain: string;
|
|
21
|
-
txtValue: string;
|
|
22
|
-
}): Promise<{
|
|
23
|
-
recordId: string;
|
|
24
|
-
fqdn: string;
|
|
25
|
-
}>;
|
|
26
|
-
cleanupDnsChallenge(input: {
|
|
27
|
-
tunnelId: string;
|
|
28
|
-
tunnelToken: string;
|
|
29
|
-
recordId: string;
|
|
30
|
-
}): Promise<void>;
|
|
31
21
|
}
|
|
32
22
|
export declare function resolveBrokerApiBase(brokerUrl: string): string;
|
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { createTunnelRegistrationProof } from "./registration-proof.js";
|
|
4
|
+
import { z } from "zod";
|
|
3
5
|
//#region src/tunnel/broker-client.ts
|
|
4
6
|
init_logger();
|
|
5
7
|
const log = createLogger("TunnelBroker");
|
|
8
|
+
var TunnelBrokerError = class extends Error {
|
|
9
|
+
constructor(status, message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.status = status;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const registrationResponseSchema = z.object({
|
|
15
|
+
tunnelId: z.string().regex(/^[a-zA-Z0-9_-]{1,128}$/),
|
|
16
|
+
tunnelToken: z.string().min(1).max(256),
|
|
17
|
+
subdomain: z.string().regex(/^[a-z0-9]{4,16}$/),
|
|
18
|
+
publicUrl: z.url(),
|
|
19
|
+
frpc: z.object({
|
|
20
|
+
serverAddr: z.string().min(1).max(253),
|
|
21
|
+
serverPort: z.number().int().min(1).max(65535),
|
|
22
|
+
authToken: z.string().min(1).max(256),
|
|
23
|
+
proxyName: z.string().regex(/^[a-zA-Z0-9_-]{1,128}$/),
|
|
24
|
+
subdomain: z.string().regex(/^[a-z0-9]{4,16}$/)
|
|
25
|
+
}),
|
|
26
|
+
expiresAt: z.iso.datetime(),
|
|
27
|
+
heartbeatIntervalMs: z.number().int().min(5e3).max(6e4)
|
|
28
|
+
});
|
|
6
29
|
var TunnelBrokerClient = class {
|
|
7
30
|
constructor(baseUrl) {
|
|
8
31
|
this.baseUrl = baseUrl;
|
|
@@ -13,39 +36,40 @@ var TunnelBrokerClient = class {
|
|
|
13
36
|
async register(input) {
|
|
14
37
|
const url = this.apiUrl("/tunnels/register");
|
|
15
38
|
const res = await fetch(url, {
|
|
39
|
+
redirect: "error",
|
|
40
|
+
signal: AbortSignal.timeout(15e3),
|
|
16
41
|
method: "POST",
|
|
17
42
|
headers: {
|
|
18
43
|
"Content-Type": "application/json",
|
|
19
44
|
"X-Registration-Secret": input.registrationSecret
|
|
20
45
|
},
|
|
21
|
-
body: JSON.stringify(
|
|
22
|
-
gatewayVersion: input.gatewayVersion,
|
|
23
|
-
platform: input.platform,
|
|
24
|
-
gatewayTokenHash: input.gatewayTokenHash,
|
|
25
|
-
preferredSubdomain: input.preferredSubdomain
|
|
26
|
-
})
|
|
46
|
+
body: JSON.stringify(createTunnelRegistrationProof(input))
|
|
27
47
|
});
|
|
28
48
|
if (!res.ok) {
|
|
29
|
-
const body = await res.text().catch(() => "");
|
|
30
49
|
log.error({
|
|
31
50
|
status: res.status,
|
|
32
|
-
url
|
|
33
|
-
bodyPreview: body.slice(0, 200)
|
|
51
|
+
url
|
|
34
52
|
}, "Tunnel register failed");
|
|
35
|
-
throw new
|
|
53
|
+
throw new TunnelBrokerError(res.status, `Tunnel register failed: ${res.status}`);
|
|
36
54
|
}
|
|
37
|
-
|
|
55
|
+
const registration = registrationResponseSchema.parse(await res.json());
|
|
56
|
+
if (new URL(registration.publicUrl).protocol !== "https:") throw new Error("Tunnel requires HTTPS");
|
|
57
|
+
return registration;
|
|
38
58
|
}
|
|
39
59
|
async heartbeat(tunnelId, tunnelToken) {
|
|
40
60
|
const res = await fetch(this.apiUrl(`/tunnels/${encodeURIComponent(tunnelId)}/heartbeat`), {
|
|
61
|
+
redirect: "error",
|
|
62
|
+
signal: AbortSignal.timeout(15e3),
|
|
41
63
|
method: "POST",
|
|
42
64
|
headers: { "X-Tunnel-Token": tunnelToken }
|
|
43
65
|
});
|
|
44
|
-
if (res.status === 401 || res.status === 410) throw new
|
|
66
|
+
if (res.status === 401 || res.status === 403 || res.status === 410) throw new TunnelBrokerError(res.status, `Tunnel heartbeat rejected: ${res.status}`);
|
|
45
67
|
if (!res.ok) throw new Error(`Tunnel heartbeat failed: ${res.status}`);
|
|
46
68
|
}
|
|
47
69
|
async deregister(tunnelId, tunnelToken) {
|
|
48
70
|
const res = await fetch(this.apiUrl(`/tunnels/${encodeURIComponent(tunnelId)}`), {
|
|
71
|
+
redirect: "error",
|
|
72
|
+
signal: AbortSignal.timeout(15e3),
|
|
49
73
|
method: "DELETE",
|
|
50
74
|
headers: { "X-Tunnel-Token": tunnelToken }
|
|
51
75
|
});
|
|
@@ -54,42 +78,6 @@ var TunnelBrokerClient = class {
|
|
|
54
78
|
status: res.status
|
|
55
79
|
}, "Tunnel deregister returned non-OK");
|
|
56
80
|
}
|
|
57
|
-
async setDnsChallenge(input) {
|
|
58
|
-
const res = await fetch(this.apiUrl("/dns/challenge"), {
|
|
59
|
-
method: "POST",
|
|
60
|
-
headers: {
|
|
61
|
-
"Content-Type": "application/json",
|
|
62
|
-
"X-Tunnel-Token": input.tunnelToken
|
|
63
|
-
},
|
|
64
|
-
body: JSON.stringify({
|
|
65
|
-
tunnelId: input.tunnelId,
|
|
66
|
-
subdomain: input.subdomain,
|
|
67
|
-
txtValue: input.txtValue
|
|
68
|
-
})
|
|
69
|
-
});
|
|
70
|
-
if (!res.ok) {
|
|
71
|
-
const body = await res.text().catch(() => "");
|
|
72
|
-
throw new Error(`Broker DNS challenge failed: ${res.status} ${body.slice(0, 200)}`);
|
|
73
|
-
}
|
|
74
|
-
return await res.json();
|
|
75
|
-
}
|
|
76
|
-
async cleanupDnsChallenge(input) {
|
|
77
|
-
const res = await fetch(this.apiUrl("/dns/cleanup"), {
|
|
78
|
-
method: "POST",
|
|
79
|
-
headers: {
|
|
80
|
-
"Content-Type": "application/json",
|
|
81
|
-
"X-Tunnel-Token": input.tunnelToken
|
|
82
|
-
},
|
|
83
|
-
body: JSON.stringify({
|
|
84
|
-
tunnelId: input.tunnelId,
|
|
85
|
-
recordId: input.recordId
|
|
86
|
-
})
|
|
87
|
-
});
|
|
88
|
-
if (!res.ok && res.status !== 404) log.warn({
|
|
89
|
-
recordId: input.recordId,
|
|
90
|
-
status: res.status
|
|
91
|
-
}, "Broker DNS cleanup returned non-OK");
|
|
92
|
-
}
|
|
93
81
|
};
|
|
94
82
|
function resolveBrokerApiBase(brokerUrl) {
|
|
95
83
|
const trimmed = brokerUrl.replace(/\/+$/, "");
|
|
@@ -97,4 +85,4 @@ function resolveBrokerApiBase(brokerUrl) {
|
|
|
97
85
|
return `${trimmed}/api`;
|
|
98
86
|
}
|
|
99
87
|
//#endregion
|
|
100
|
-
export { TunnelBrokerClient, resolveBrokerApiBase };
|
|
88
|
+
export { TunnelBrokerClient, TunnelBrokerError, resolveBrokerApiBase };
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { type FrpcReleasePlatform } from './frpc-extract.js';
|
|
2
|
+
import { FRPC_VERSION } from './frpc-release.js';
|
|
2
3
|
import type { FrpcDownloadProgress } from './tunnel-types.js';
|
|
3
|
-
export
|
|
4
|
+
export { FRPC_VERSION };
|
|
4
5
|
export type { FrpcDownloadProgress };
|
|
5
6
|
export type EnsureFrpcBinaryOptions = {
|
|
6
7
|
onProgress?: (progress: FrpcDownloadProgress) => void;
|
|
8
|
+
platform?: FrpcReleasePlatform;
|
|
9
|
+
arch?: string;
|
|
7
10
|
};
|
|
8
|
-
export declare function buildFrpcReleaseBasename(
|
|
9
|
-
export declare function frpcDownloadUrlsForTarget(
|
|
10
|
-
|
|
11
|
-
export declare function publishFrpcPathForProcess(
|
|
12
|
-
/** Clear runtime frpc path when the tunnel stops (no bundled Electron binary). */
|
|
11
|
+
export declare function buildFrpcReleaseBasename(platform: FrpcReleasePlatform, arch: string, version?: string): string;
|
|
12
|
+
export declare function frpcDownloadUrlsForTarget(platform: FrpcReleasePlatform, arch: string, version?: string): string[];
|
|
13
|
+
export declare function verifyFrpcDigest(path: string, expected: string): Promise<void>;
|
|
14
|
+
export declare function publishFrpcPathForProcess(path: string): void;
|
|
13
15
|
export declare function clearFrpcPathForProcess(): void;
|
|
14
16
|
export declare function ensureFrpcBinary(opts?: EnsureFrpcBinaryOptions): Promise<string>;
|
|
@@ -2,127 +2,115 @@ import { createLogger } from "../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
3
|
import { init_paths, resolveBinDir } from "../config/paths.js";
|
|
4
4
|
import { extractFrpcFromReleaseArchive, frpcReleaseArchiveExtension, nodePlatformForFrpTarget } from "./frpc-extract.js";
|
|
5
|
-
import {
|
|
5
|
+
import { FRPC_RELEASES, FRPC_VERSION } from "./frpc-release.js";
|
|
6
6
|
import { join } from "node:path";
|
|
7
|
-
import { chmodSync, createWriteStream, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
8
|
-
import {
|
|
7
|
+
import { chmodSync, createReadStream, createWriteStream, existsSync, mkdirSync, mkdtempSync, renameSync, rmSync } from "node:fs";
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
9
|
import { pipeline } from "node:stream/promises";
|
|
10
|
-
import { Readable } from "node:stream";
|
|
10
|
+
import { Readable, Transform } from "node:stream";
|
|
11
11
|
//#region src/tunnel/frpc-binary.ts
|
|
12
12
|
init_paths();
|
|
13
13
|
init_logger();
|
|
14
14
|
const log = createLogger("TunnelFrpc");
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
linux: "linux",
|
|
19
|
-
win32: "windows"
|
|
20
|
-
};
|
|
21
|
-
const ARCH_MAP = {
|
|
22
|
-
x64: "amd64",
|
|
23
|
-
arm64: "arm64",
|
|
24
|
-
ia32: "386"
|
|
25
|
-
};
|
|
26
|
-
function buildFrpcReleaseBasename(frpPlatform, arch, version = FRPC_VERSION) {
|
|
27
|
-
return `frp_${version}_${frpPlatform}_${arch}`;
|
|
15
|
+
const MAX_ARCHIVE_BYTES = 64 * 1024 * 1024;
|
|
16
|
+
function buildFrpcReleaseBasename(platform, arch, version = FRPC_VERSION) {
|
|
17
|
+
return `frp_${version}_${platform}_${arch}`;
|
|
28
18
|
}
|
|
29
|
-
function frpcDownloadUrlsForTarget(
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
return [
|
|
33
|
-
`https://frp.xopc.ai/bin/${folder}${ext}`,
|
|
34
|
-
`https://github.com/fatedier/frp/releases/download/v${version}/${folder}${ext}`,
|
|
35
|
-
`https://ghfast.top/https://github.com/fatedier/frp/releases/download/v${version}/${folder}${ext}`
|
|
36
|
-
];
|
|
19
|
+
function frpcDownloadUrlsForTarget(platform, arch, version = FRPC_VERSION) {
|
|
20
|
+
const archive = buildFrpcReleaseBasename(platform, arch, version) + frpcReleaseArchiveExtension(platform);
|
|
21
|
+
return [`https://frp.xopc.ai/bin/${archive}`, `https://github.com/fatedier/frp/releases/download/v${version}/${archive}`];
|
|
37
22
|
}
|
|
38
|
-
function
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
platform,
|
|
43
|
-
arch,
|
|
44
|
-
folder: buildFrpcReleaseBasename(platform, arch)
|
|
45
|
-
};
|
|
23
|
+
async function verifyFrpcDigest(path, expected) {
|
|
24
|
+
const hash = createHash("sha256");
|
|
25
|
+
await pipeline(createReadStream(path), hash);
|
|
26
|
+
if (hash.digest("hex") !== expected) throw new Error("COMPONENT_VERIFY_FAILED: frpc checksum mismatch");
|
|
46
27
|
}
|
|
47
|
-
function
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
28
|
+
async function downloadToFile(url, path, onProgress) {
|
|
29
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(6e4) });
|
|
30
|
+
if (!response.ok || !response.body) throw new Error(`frpc download failed: ${response.status}`);
|
|
31
|
+
const length = Number(response.headers.get("content-length"));
|
|
32
|
+
const totalBytes = length > 0 ? length : null;
|
|
33
|
+
if (totalBytes && totalBytes > MAX_ARCHIVE_BYTES) {
|
|
34
|
+
await response.body.cancel();
|
|
35
|
+
throw new Error("frpc archive exceeds size limit");
|
|
36
|
+
}
|
|
56
37
|
let bytesReceived = 0;
|
|
57
|
-
const
|
|
38
|
+
const bounded = new Transform({ transform(chunk, _encoding, callback) {
|
|
39
|
+
bytesReceived += chunk.length;
|
|
40
|
+
if (bytesReceived > MAX_ARCHIVE_BYTES) return callback(/* @__PURE__ */ new Error("frpc archive exceeds size limit"));
|
|
58
41
|
onProgress?.({
|
|
59
42
|
phase: "downloading",
|
|
60
43
|
url,
|
|
61
44
|
bytesReceived,
|
|
62
45
|
totalBytes,
|
|
63
|
-
percent: totalBytes
|
|
46
|
+
percent: totalBytes ? Math.min(100, Math.round(bytesReceived / totalBytes * 100)) : null
|
|
64
47
|
});
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
nodeStream.on("data", (chunk) => {
|
|
69
|
-
bytesReceived += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
|
|
70
|
-
report();
|
|
71
|
-
});
|
|
72
|
-
await pipeline(nodeStream, createWriteStream(destPath));
|
|
73
|
-
report();
|
|
48
|
+
callback(null, chunk);
|
|
49
|
+
} });
|
|
50
|
+
await pipeline(Readable.fromWeb(response.body), bounded, createWriteStream(path, { mode: 384 }));
|
|
74
51
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
process.env.XOPC_FRPC_PATH = binPath;
|
|
52
|
+
function publishFrpcPathForProcess(path) {
|
|
53
|
+
process.env.XOPC_FRPC_PATH = path;
|
|
78
54
|
}
|
|
79
|
-
/** Clear runtime frpc path when the tunnel stops (no bundled Electron binary). */
|
|
80
55
|
function clearFrpcPathForProcess() {
|
|
81
56
|
delete process.env.XOPC_FRPC_PATH;
|
|
82
57
|
}
|
|
83
|
-
async function ensureFrpcBinary(opts) {
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
const
|
|
89
|
-
|
|
58
|
+
async function ensureFrpcBinary(opts = {}) {
|
|
59
|
+
const platform = opts.platform ?? (process.platform === "win32" ? "windows" : process.platform);
|
|
60
|
+
const arch = opts.arch ?? (process.arch === "x64" ? "amd64" : process.arch);
|
|
61
|
+
const target = `${platform}_${arch}`;
|
|
62
|
+
if (!Object.hasOwn(FRPC_RELEASES, target)) throw new Error(`Unsupported frpc target: ${target}`);
|
|
63
|
+
const release = FRPC_RELEASES[target];
|
|
64
|
+
const fromEnv = !opts.platform && !opts.arch ? process.env.XOPC_FRPC_PATH?.trim() : void 0;
|
|
65
|
+
if (fromEnv) {
|
|
66
|
+
await verifyFrpcDigest(fromEnv, release.binary);
|
|
67
|
+
return fromEnv;
|
|
68
|
+
}
|
|
69
|
+
const cacheDir = join(resolveBinDir(), "frpc", FRPC_VERSION, target);
|
|
70
|
+
mkdirSync(cacheDir, {
|
|
71
|
+
recursive: true,
|
|
72
|
+
mode: 448
|
|
73
|
+
});
|
|
74
|
+
chmodSync(cacheDir, 448);
|
|
75
|
+
const binName = platform === "windows" ? "frpc.exe" : "frpc";
|
|
90
76
|
const cachePath = join(cacheDir, binName);
|
|
91
|
-
if (existsSync(cachePath))
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
77
|
+
if (existsSync(cachePath)) try {
|
|
78
|
+
await verifyFrpcDigest(cachePath, release.binary);
|
|
79
|
+
return cachePath;
|
|
80
|
+
} catch {
|
|
81
|
+
log.warn({ target }, "Discarding unverified frpc cache");
|
|
82
|
+
}
|
|
83
|
+
const temporary = mkdtempSync(join(cacheDir, ".download-"));
|
|
84
|
+
const archivePath = join(temporary, "release" + frpcReleaseArchiveExtension(platform));
|
|
85
|
+
const executablePath = join(temporary, binName);
|
|
86
|
+
let lastError;
|
|
98
87
|
try {
|
|
99
|
-
for (const url of
|
|
100
|
-
|
|
101
|
-
await
|
|
102
|
-
onProgress?.({
|
|
88
|
+
for (const url of frpcDownloadUrlsForTarget(platform, arch)) try {
|
|
89
|
+
await downloadToFile(url, archivePath, opts.onProgress);
|
|
90
|
+
await verifyFrpcDigest(archivePath, release.archive);
|
|
91
|
+
opts.onProgress?.({
|
|
103
92
|
phase: "extracting",
|
|
104
|
-
url
|
|
105
|
-
bytesReceived: 0,
|
|
106
|
-
totalBytes: null,
|
|
107
|
-
percent: null
|
|
93
|
+
url
|
|
108
94
|
});
|
|
109
|
-
await extractFrpcFromReleaseArchive(archivePath,
|
|
110
|
-
|
|
95
|
+
await extractFrpcFromReleaseArchive(archivePath, executablePath, buildFrpcReleaseBasename(platform, arch), nodePlatformForFrpTarget(platform));
|
|
96
|
+
await verifyFrpcDigest(executablePath, release.binary);
|
|
97
|
+
if (platform !== "windows") chmodSync(executablePath, 448);
|
|
98
|
+
renameSync(executablePath, cachePath);
|
|
111
99
|
return cachePath;
|
|
112
|
-
} catch (
|
|
113
|
-
|
|
100
|
+
} catch (error) {
|
|
101
|
+
lastError = error;
|
|
114
102
|
log.warn({
|
|
115
103
|
url,
|
|
116
|
-
err
|
|
117
|
-
}, "frpc download
|
|
104
|
+
err: error
|
|
105
|
+
}, "Verified frpc download failed");
|
|
118
106
|
}
|
|
119
107
|
} finally {
|
|
120
|
-
rmSync(
|
|
108
|
+
rmSync(temporary, {
|
|
121
109
|
recursive: true,
|
|
122
110
|
force: true
|
|
123
111
|
});
|
|
124
112
|
}
|
|
125
|
-
throw new Error(`Failed to
|
|
113
|
+
throw new Error(`Failed to obtain verified frpc for ${target}`, { cause: lastError });
|
|
126
114
|
}
|
|
127
115
|
//#endregion
|
|
128
|
-
export { FRPC_VERSION, buildFrpcReleaseBasename, clearFrpcPathForProcess, ensureFrpcBinary, frpcDownloadUrlsForTarget, publishFrpcPathForProcess };
|
|
116
|
+
export { FRPC_VERSION, buildFrpcReleaseBasename, clearFrpcPathForProcess, ensureFrpcBinary, frpcDownloadUrlsForTarget, publishFrpcPathForProcess, verifyFrpcDigest };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { TunnelRegistration } from './tunnel-types.js';
|
|
2
2
|
export declare function resolveFrpcConfigPath(tunnelId: string): string;
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function removeFrpcConfig(tunnelId: string): void;
|
|
4
|
+
export declare function writeFrpcConfig(registration: TunnelRegistration, localPort: number, localHost?: string): string;
|
|
@@ -1,34 +1,51 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { chmodSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { rootCertificates } from "node:tls";
|
|
5
6
|
//#region src/tunnel/frpc-config.ts
|
|
6
7
|
init_paths();
|
|
7
8
|
function resolveFrpcConfigPath(tunnelId) {
|
|
9
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(tunnelId)) throw new Error("Invalid tunnel id");
|
|
8
10
|
const tmpDir = join(resolveStateDir(), "tmp");
|
|
9
|
-
mkdirSync(tmpDir, {
|
|
11
|
+
mkdirSync(tmpDir, {
|
|
12
|
+
recursive: true,
|
|
13
|
+
mode: 448
|
|
14
|
+
});
|
|
15
|
+
chmodSync(tmpDir, 448);
|
|
10
16
|
return join(tmpDir, `frpc-${tunnelId}.toml`);
|
|
11
17
|
}
|
|
12
|
-
function
|
|
18
|
+
function removeFrpcConfig(tunnelId) {
|
|
19
|
+
rmSync(resolveFrpcConfigPath(tunnelId), { force: true });
|
|
20
|
+
}
|
|
21
|
+
function writeFrpcConfig(registration, localPort, localHost = "127.0.0.1") {
|
|
13
22
|
const configPath = resolveFrpcConfigPath(registration.tunnelId);
|
|
23
|
+
const caPath = join(resolveStateDir(), "tmp", "frp-trusted-roots.pem");
|
|
24
|
+
writeFileSync(caPath, rootCertificates.join("\n"), { mode: 384 });
|
|
14
25
|
const { frpc } = registration;
|
|
26
|
+
for (const port of [localPort, frpc.serverPort]) if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("Invalid tunnel port");
|
|
27
|
+
const quote = JSON.stringify;
|
|
15
28
|
writeFileSync(configPath, `# Auto-generated by xopc — do not edit
|
|
16
|
-
serverAddr =
|
|
29
|
+
serverAddr = ${quote(frpc.serverAddr)}
|
|
17
30
|
serverPort = ${frpc.serverPort}
|
|
18
|
-
metadatas.token =
|
|
19
|
-
|
|
31
|
+
metadatas.token = ${quote(frpc.authToken)}
|
|
20
32
|
loginFailExit = false
|
|
33
|
+
transport.tls.enable = true
|
|
34
|
+
transport.tls.serverName = ${quote(frpc.serverAddr)}
|
|
35
|
+
transport.tls.trustedCaFile = ${quote(caPath)}
|
|
21
36
|
transport.heartbeatInterval = 10
|
|
22
37
|
transport.heartbeatTimeout = 30
|
|
23
38
|
|
|
24
39
|
[[proxies]]
|
|
25
|
-
name =
|
|
26
|
-
type = "
|
|
27
|
-
localIP =
|
|
40
|
+
name = ${quote(frpc.proxyName)}
|
|
41
|
+
type = "http"
|
|
42
|
+
localIP = ${quote(localHost)}
|
|
28
43
|
localPort = ${localPort}
|
|
29
|
-
subdomain =
|
|
30
|
-
|
|
44
|
+
subdomain = ${quote(frpc.subdomain)}
|
|
45
|
+
hostHeaderRewrite = ${quote(new URL(registration.publicUrl).hostname)}
|
|
46
|
+
`, { mode: 384 });
|
|
47
|
+
chmodSync(configPath, 384);
|
|
31
48
|
return configPath;
|
|
32
49
|
}
|
|
33
50
|
//#endregion
|
|
34
|
-
export { resolveFrpcConfigPath, writeFrpcConfig };
|
|
51
|
+
export { removeFrpcConfig, resolveFrpcConfigPath, writeFrpcConfig };
|