@xopcai/xopc 0.0.270 → 0.0.273
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/README.md +1 -5
- package/README.zh-CN.md +1 -5
- package/dist/browser-ext/dist/assets/{auth-cwEj8rFb.js → auth-DkwOUI6_.js} +132 -33
- package/dist/browser-ext/dist/background.js +2 -2
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +46 -32
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-D_0FmdRj.js → activity-store-cF7IX2RP.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-IZvEXak_.js → agent-avatar-dicebear-BrgxX8nG.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DvhuRCLA.js +1 -0
- package/dist/gateway/static/root/assets/agents-C0By2FIo.js +1 -0
- package/dist/gateway/static/root/assets/{api-O3TTQ4qN.js → api-CYkdUpkx.js} +1 -1
- package/dist/gateway/static/root/assets/app-link-BiBXVEvp.js +1 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Cqqsbzri.js → app-management-settings-panel-DfoNzWIa.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DaJyf32s.js → appearance-settings-czbLdCqj.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BSJXKWcE.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-kDPnDTJI.js → archive-plugin-D14P13mX.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CJ3VceKS.js → attachment-load-Dok_B1Gv.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-JwMtU8XB.js → automations-page-DM7ZEewI.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace--1TsZf3O.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DzyZXLBX.js → binary-plugins-CxNg6InF.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-kTt3gYIJ.js → block-editor-D22VcYnC.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-BKohPYR4.js → browser-automation-inputs-6NWTLEpd.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-ktQfFPk-.js → browser-automations-page-BrqySdbW.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-DOHgQer_.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Bpse_5K-.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-yHsY174W.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-DrqzYmDr.js → channels-status-swr-BUZimNmp.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CIFGGLGa.js → chat-terminal-dock-CZPBNpMI.js} +2 -2
- package/dist/gateway/static/root/assets/clock-3-DnrAnuyZ.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-B_wLKGnH.js +2 -0
- package/dist/gateway/static/root/assets/cron-expression-C26e13YU.js +2 -0
- package/dist/gateway/static/root/assets/date-picker-Da_0QyLe.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-D3vNIjRI.js → dependency-picker-D_djqzy7.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-fQwRb_3p.js → desktop-pet-Celmbw-T.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DfOJ-GvT.js → desktop-pet-settings-CqNNgF45.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-B5_w9qlm.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Cn53jB5-.js → extension-debug-page-ku3kCjvH.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-IDpLCxpC.js → extension-page-C7FpHwL4.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-OMj2tU2_.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-swr-B7dcmP7Q.js → gateway-config-swr-6eb1vKE1.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-CH-6vkgN.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-JGhGMhVZ.js → gateway-startup-retry-DUFFCU8H.js} +1 -1
- package/dist/gateway/static/root/assets/git-branch-Dh9uxTot.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-CSFzOACM.js +1 -0
- package/dist/gateway/static/root/assets/home-page-BJebAKB-.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-BJLX7Qrh.js → image-generation-api-C1cHRBRp.js} +1 -1
- package/dist/gateway/static/root/assets/index-C6OWYFtQ.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-BuvD3iv8.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-CaC4-THD.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-APCMNDvU.js → local-apps-page-DdJ8zwBp.js} +1 -1
- package/dist/gateway/static/root/assets/locale-store-BBSCIl4I.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-BaR2he0K.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-r-iYWZFY.js +1 -0
- package/dist/gateway/static/root/assets/markdown-view-c5vtnYe8.js +201 -0
- package/dist/gateway/static/root/assets/{media-plugins-C10byeaa.js → media-plugins-D_a6GDY6.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-DjuBdDCn.js} +3 -3
- package/dist/gateway/static/root/assets/note-detail-panel-BV6nbgac.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-BmLKoWwi.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-qQ36zncF.js → page-tabs-C7Le9bSI.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-B2pOxJBK.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-card-CcNBqHoH.js → proactive-card-BlQ1vCtV.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-page-C3K61jve.js → proactive-page-CghKTfYa.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CunnDP4w.js → product-open-page-DpjiHgwu.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-CV8Lh296.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-COweOaJP.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-0JSegbNl.js → registry-api-CyQ4k1Ux.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-ChPPGVU5.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-bu_mwBTr.js → runtime-tools-settings-panel-Bl4ArLHf.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-BE0sgZyz.js → schema-form-KQFmfWd4.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DgmHibOK.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DV7kMco2.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CBo517lV.js → settings-form-section-Dbnls9ty.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DBPimx93.js → settings-page-CDKirYRG.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-SQmtWoOs.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-DdV75VTe.js → share-preview-page-DwgLjS1m.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-Cs5bUrYw.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DyKrjq7F.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-Cn_-nvRo.js → skills-page-Bd0_ED_p.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page.utils-rA-XT-YG.js +1 -0
- package/dist/gateway/static/root/assets/system-settings-panel-CSkMrHLz.js +1 -0
- package/dist/gateway/static/root/assets/task-detail-page-CEQU-L_G.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-1wryLgBQ.js → theme-store-DWpIEWen.js} +1 -1
- package/dist/gateway/static/root/assets/tunnel-api-COJcGnEi.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-N_lm4FdD.js → use-autosave-DkQAIAuB.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-BQAU55lf.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DMsyVfri.js → voice-api-key-field-BrqcH0P-.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-QWVmiAp3.js → voice-config-api-BJ95Z3pT.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BC0vAxp1.js → work-discovery-overlay-vfTWKm13.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Cz9jQIlP.js → workflow-run-setup-panel-CHdr_ng9.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-hwRJD7vR.js +6 -0
- package/dist/gateway/static/root/index.html +16 -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/browser/providers/browser-ext-install.d.ts +6 -0
- package/dist/src/browser/providers/browser-ext-install.js +16 -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/run-foreground.js +8 -5
- package/dist/src/cli/commands/gateway/service.js +4 -3
- package/dist/src/cli/commands/gateway/token.js +28 -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/device-routes.js +4 -3
- 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/browser.js +26 -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 +3 -4
- 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 +3 -3
- 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/markdown-view-BwjpJVPs.js +0 -201
- 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
|
@@ -2,8 +2,8 @@ import { createLogger } from "../../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
4
4
|
import { getAllProviders, init_providers } from "../../providers/index.js";
|
|
5
|
-
import { disconnectProvider } from "../../providers/provider-disconnect.js";
|
|
6
5
|
import { formatExamples, register } from "../registry.js";
|
|
6
|
+
import { disconnectProvider } from "../../providers/provider-disconnect.js";
|
|
7
7
|
import { colorizeStatus, colors } from "../utils/colors.js";
|
|
8
8
|
import { listAllProfiles, listProfilesForProvider, removeAuthProfile, upsertAuthProfile } from "../../auth/profiles/profiles.js";
|
|
9
9
|
import { getOAuthProvider, getSupportedOAuthProviders } from "../utils/oauth-providers.js";
|
|
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
52
52
|
id: "database-schema",
|
|
53
53
|
label: "Database schema",
|
|
54
54
|
status: "pass",
|
|
55
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
55
|
+
message: `SQLite schema v${status.dbVersion} (current release v165).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -5,10 +5,10 @@ import { init_paths, resolveConfigPath, resolveExtensionsDir } from "../../confi
|
|
|
5
5
|
import { init_normalize_manifest, normalizeExtensionManifest } from "../../extensions/normalize-manifest.js";
|
|
6
6
|
import { init_loader, loadConfig } from "../../config/loader.js";
|
|
7
7
|
import { checkEngineCompatibility } from "../../extensions/engine-check.js";
|
|
8
|
+
import { getContextWithOpts } from "../context.js";
|
|
8
9
|
import { GatewayServer } from "../../gateway/server.js";
|
|
9
10
|
import { runGatewayLoop } from "../../gateway/run-loop.js";
|
|
10
11
|
import "../../gateway/index.js";
|
|
11
|
-
import { getContextWithOpts } from "../context.js";
|
|
12
12
|
import { colors } from "../utils/colors.js";
|
|
13
13
|
import { initWorkspace } from "../utils/init-workspace.js";
|
|
14
14
|
import { join, resolve } from "node:path";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { init_paths, resolveExtensionsDir } from "../../config/paths.js";
|
|
2
2
|
import { init_loader, loadConfig } from "../../config/loader.js";
|
|
3
3
|
import { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl, verifyStoreArtifactSha256 } from "../../agent/skills/marketplace/adapters/store/store-api-client.js";
|
|
4
|
+
import { getContextWithOpts } from "../context.js";
|
|
4
5
|
import { getExtensionLockfileManager } from "../../extensions/lockfile.js";
|
|
5
6
|
import { installFromLocal, installFromNpm, peekExtensionManifestFromStoreZip } from "../../extensions/install.js";
|
|
6
7
|
import { commitStagedExtensionInstall, finalizeStagedExtensionInstall, rollbackStagedExtensionInstall, stageExtensionStoreZip } from "../../extensions/install-transaction.js";
|
|
7
8
|
import { fetchRegistry, findExtension, getExtensionMarketplaceStoreBaseUrl, listExtensions, searchExtensions } from "../../extensions/marketplace.js";
|
|
8
|
-
import { getContextWithOpts } from "../context.js";
|
|
9
9
|
import { colors } from "../utils/colors.js";
|
|
10
10
|
import { validateExtensionPackageDirectory } from "./extension-pack.js";
|
|
11
11
|
import { join, resolve } from "node:path";
|
|
@@ -5,10 +5,10 @@ import { init_paths, resolveExtensionsDir } from "../../config/paths.js";
|
|
|
5
5
|
import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
|
|
6
6
|
import { checkEngineCompatibility } from "../../extensions/engine-check.js";
|
|
7
7
|
import { ExtensionLoader } from "../../extensions/loader.js";
|
|
8
|
+
import { getContextWithOpts } from "../context.js";
|
|
8
9
|
import { getExtensionLockfileManager } from "../../extensions/lockfile.js";
|
|
9
10
|
import { checkAllExtensionsHealth, getExtensionHealthChecker } from "../../extensions/health.js";
|
|
10
11
|
import { collectExtensionPackageDependencyIssues } from "../../extensions/package-contract.js";
|
|
11
|
-
import { getContextWithOpts } from "../context.js";
|
|
12
12
|
import { colors } from "../utils/colors.js";
|
|
13
13
|
import { createExtensionCreateCommand } from "./extension-create.js";
|
|
14
14
|
import { createExtensionDevCommand } from "./extension-dev.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { init_paths, resolveConfigPath } from "../../../config/paths.js";
|
|
2
2
|
import { loadConfig } from "../../../config/loader.js";
|
|
3
|
-
import { isRestartEnabled } from "../../../config/commands.flags.js";
|
|
4
3
|
import "../../../config/index.js";
|
|
4
|
+
import { isRestartEnabled } from "../../../config/commands.flags.js";
|
|
5
5
|
import { resolveGatewayService } from "../../../daemon/service.js";
|
|
6
6
|
import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "../../../infra/restart.js";
|
|
7
7
|
import { findVerifiedGatewayListenerPidsOnPortSync, formatGatewayPidList, signalVerifiedGatewayPidSync } from "../../../infra/gateway-processes.js";
|
|
@@ -69,10 +69,13 @@ async function runGatewayFromCliOptions(options, ctx) {
|
|
|
69
69
|
const { resolveGatewayAuth, assertGatewayAuthConfigured } = await import("../../../gateway/auth.js");
|
|
70
70
|
const { assertGatewayRuntimeConfig } = await import("../../../gateway/runtime-config.js");
|
|
71
71
|
let auth = resolveGatewayAuth({ authConfig: effectiveConfig.gateway?.auth });
|
|
72
|
-
if (typeof options.token === "string" && options.token.trim().length > 0)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
if (typeof options.token === "string" && options.token.trim().length > 0) {
|
|
73
|
+
auth = {
|
|
74
|
+
mode: "token",
|
|
75
|
+
token: options.token.trim()
|
|
76
|
+
};
|
|
77
|
+
process.env.XOPC_GATEWAY_TOKEN = auth.token;
|
|
78
|
+
}
|
|
76
79
|
try {
|
|
77
80
|
assertGatewayAuthConfigured(auth);
|
|
78
81
|
assertGatewayRuntimeConfig({
|
|
@@ -126,7 +129,7 @@ async function runGatewayFromCliOptions(options, ctx) {
|
|
|
126
129
|
});
|
|
127
130
|
await server.start();
|
|
128
131
|
const displayHost = bindHost === "0.0.0.0" ? "localhost" : bindHost;
|
|
129
|
-
const token =
|
|
132
|
+
const token = auth.mode === "token" ? auth.token : void 0;
|
|
130
133
|
console.log("✅ Gateway started");
|
|
131
134
|
console.log(` URL: http://${displayHost}:${port}`);
|
|
132
135
|
if (token) console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);
|
|
@@ -9,8 +9,9 @@ init_paths();
|
|
|
9
9
|
* Create service install subcommand - actually installs the OS service
|
|
10
10
|
*/
|
|
11
11
|
function createInstallCommand() {
|
|
12
|
-
return new Command("install").description("Install gateway as OS service (LaunchAgent / systemd / Task)").option("--port <port>", "Gateway port").option("--token <token>", "Gateway auth token").option("--force", "Force reinstall if already installed").option("--json", "Output JSON").action(async (options) => {
|
|
12
|
+
return new Command("install").description("Install gateway as OS service (LaunchAgent / systemd / Task)").option("--port <port>", "Gateway port").option("--token <token>", "Gateway auth token").option("--force", "Force reinstall if already installed").option("--json", "Output JSON").action(async (options, command) => {
|
|
13
13
|
const configPath = getContextWithOpts().configPath || resolveConfigPath();
|
|
14
|
+
const force = options.force === true || command.optsWithGlobals().force === true;
|
|
14
15
|
const [{ loadConfig }, { resolveGatewayService, isDaemonAvailableAsync, getPlatformName }, { buildGatewayInstallArgs }] = await Promise.all([
|
|
15
16
|
import("../../../config/index.js"),
|
|
16
17
|
import("../../../daemon/service.js"),
|
|
@@ -30,7 +31,7 @@ function createInstallCommand() {
|
|
|
30
31
|
}
|
|
31
32
|
const service = await resolveGatewayService();
|
|
32
33
|
const loaded = await service.isLoaded({ env: process.env });
|
|
33
|
-
if (loaded && !
|
|
34
|
+
if (loaded && !force) {
|
|
34
35
|
if (options.json) console.log(JSON.stringify({
|
|
35
36
|
ok: true,
|
|
36
37
|
result: "already-installed"
|
|
@@ -38,7 +39,7 @@ function createInstallCommand() {
|
|
|
38
39
|
else console.log("ℹ️ Service already installed. Use --force to reinstall.");
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
41
|
-
if (loaded &&
|
|
42
|
+
if (loaded && force) try {
|
|
42
43
|
await service.uninstall({ env: process.env });
|
|
43
44
|
} catch {}
|
|
44
45
|
const installArgs = buildGatewayInstallArgs({
|
|
@@ -4,6 +4,17 @@ import crypto from "crypto";
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
//#region src/cli/commands/gateway/token.ts
|
|
6
6
|
init_paths();
|
|
7
|
+
async function readInstalledServiceToken() {
|
|
8
|
+
try {
|
|
9
|
+
const { isDaemonAvailableAsync, resolveGatewayService } = await import("../../../daemon/service.js");
|
|
10
|
+
if (!await isDaemonAvailableAsync()) return void 0;
|
|
11
|
+
const service = await resolveGatewayService();
|
|
12
|
+
if (!await service.isLoaded({ env: process.env })) return void 0;
|
|
13
|
+
return (await service.readCommand(process.env))?.environment?.XOPC_GATEWAY_TOKEN?.trim() || void 0;
|
|
14
|
+
} catch {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
7
18
|
/**
|
|
8
19
|
* Create the token subcommand for managing gateway authentication token.
|
|
9
20
|
*/
|
|
@@ -14,6 +25,7 @@ function createTokenCommand() {
|
|
|
14
25
|
const log = createLogger("GatewayTokenCommand");
|
|
15
26
|
try {
|
|
16
27
|
const config = loadConfig(configPath);
|
|
28
|
+
const installedServiceToken = await readInstalledServiceToken();
|
|
17
29
|
if (options.generate) {
|
|
18
30
|
const newToken = crypto.randomBytes(24).toString("hex");
|
|
19
31
|
config.gateway = config.gateway || {};
|
|
@@ -31,9 +43,16 @@ function createTokenCommand() {
|
|
|
31
43
|
console.log("");
|
|
32
44
|
console.log("Or set environment variable:");
|
|
33
45
|
console.log(` export XOPC_GATEWAY_TOKEN=${newToken}`);
|
|
46
|
+
if (installedServiceToken && installedServiceToken !== newToken) {
|
|
47
|
+
console.log("");
|
|
48
|
+
console.log("⚠️ The installed gateway service still uses its previous token.");
|
|
49
|
+
console.log(" Run `xopc gateway service install --force`, then restart the service.");
|
|
50
|
+
}
|
|
34
51
|
process.exit(0);
|
|
35
52
|
} else {
|
|
36
|
-
const
|
|
53
|
+
const configToken = config.gateway?.auth?.token?.trim();
|
|
54
|
+
const environmentToken = process.env.XOPC_GATEWAY_TOKEN?.trim();
|
|
55
|
+
const currentToken = installedServiceToken || environmentToken || configToken;
|
|
37
56
|
if ((config.gateway?.auth?.mode || "token") === "none") {
|
|
38
57
|
console.log("⚠️ Gateway authentication is disabled (mode: none)");
|
|
39
58
|
console.log("");
|
|
@@ -46,6 +65,14 @@ function createTokenCommand() {
|
|
|
46
65
|
console.log(` ${currentToken}`);
|
|
47
66
|
console.log("");
|
|
48
67
|
console.log(`Preview: ${tokenPreview}`);
|
|
68
|
+
if (installedServiceToken) console.log("Source: installed gateway service");
|
|
69
|
+
else if (environmentToken) console.log("Source: XOPC_GATEWAY_TOKEN");
|
|
70
|
+
else console.log(`Source: ${configPath}`);
|
|
71
|
+
if (installedServiceToken && configToken && installedServiceToken !== configToken) {
|
|
72
|
+
console.log("");
|
|
73
|
+
console.log("⚠️ Token drift detected: the installed service token overrides the config token.");
|
|
74
|
+
console.log(" Run `xopc gateway service install --force`, then restart the service to sync.");
|
|
75
|
+
}
|
|
49
76
|
console.log("");
|
|
50
77
|
console.log("Usage:");
|
|
51
78
|
console.log(` xopc gateway --token ${currentToken}`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { startSshPortForward } from "../../infra/ssh-tunnel.js";
|
|
2
1
|
import { formatExamples } from "../registry.js";
|
|
2
|
+
import { startSshPortForward } from "../../infra/ssh-tunnel.js";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
//#region src/cli/commands/gateway-ssh-tunnel.ts
|
|
5
5
|
function registerGatewaySshTunnelCommand(parent, ctx) {
|
|
@@ -2,11 +2,11 @@ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
|
2
2
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
3
3
|
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
4
4
|
import { getAllModels, getAvailableModels, getConfiguredProviders, getProviderAuthState, getProviderDisplayName, init_providers, isProviderConfigured, providerSupportsApiKey, providerSupportsOAuth, resolveModel } from "../../providers/index.js";
|
|
5
|
+
import { formatExamples, register } from "../registry.js";
|
|
6
|
+
import { getContextWithOpts } from "../context.js";
|
|
5
7
|
import "../../config/index.js";
|
|
6
8
|
import { prepareUpdateGlobalDefaults } from "../../gateway/global-defaults-admin.js";
|
|
7
9
|
import { disconnectProvider } from "../../providers/provider-disconnect.js";
|
|
8
|
-
import { formatExamples, register } from "../registry.js";
|
|
9
|
-
import { getContextWithOpts } from "../context.js";
|
|
10
10
|
import { colors } from "../utils/colors.js";
|
|
11
11
|
import { runCliOAuthLogin } from "../utils/oauth-login.js";
|
|
12
12
|
import { input } from "@inquirer/prompts";
|
|
@@ -2,8 +2,8 @@ import { init_paths_state, resolveStateDir } from "../../config/paths-state.js";
|
|
|
2
2
|
import { ConfigSchema, init_schema } from "../../config/schema.js";
|
|
3
3
|
import { saveConfig } from "../../config/loader.js";
|
|
4
4
|
import { resolveGatewayLocalClientHost } from "../../config/gateway-bind.js";
|
|
5
|
-
import "../../config/index.js";
|
|
6
5
|
import { formatExamples, register } from "../registry.js";
|
|
6
|
+
import "../../config/index.js";
|
|
7
7
|
import { provisionEagerRuntimes } from "../../runtime-tools/bootstrap.js";
|
|
8
8
|
import { colors } from "../utils/colors.js";
|
|
9
9
|
import { initWorkspace } from "../utils/init-workspace.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
2
|
-
import "../../config/index.js";
|
|
3
2
|
import { formatExamples, register } from "../registry.js";
|
|
3
|
+
import "../../config/index.js";
|
|
4
4
|
import { PLATFORM_RUNTIME_PROFILE, PLATFORM_RUNTIME_PROVIDER, PlatformRuntimeClient, discoverPlatform } from "../../platform/client.js";
|
|
5
5
|
import "../../platform/index.js";
|
|
6
6
|
import { getProfile, upsertAuthProfile } from "../../auth/profiles/profiles.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { createProfile, deleteProfile, getCurrentProfile, getSwitchCommand, listProfiles, resolveProfileStateDir } from "../../config/profile.js";
|
|
4
3
|
import { formatExamples, register } from "../registry.js";
|
|
4
|
+
import { createProfile, deleteProfile, getCurrentProfile, getSwitchCommand, listProfiles, resolveProfileStateDir } from "../../config/profile.js";
|
|
5
5
|
import { colors } from "../utils/colors.js";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import Table from "cli-table3";
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { isXopcDatabaseOpen, openXopcDatabase } from "../../storage/sqlite/connection.js";
|
|
3
4
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
4
5
|
import { resolveGatewayEffectiveHost } from "../../config/gateway-bind.js";
|
|
5
6
|
import { ensureFrpcBinary } from "../../tunnel/frpc-binary.js";
|
|
6
7
|
import { resolveTunnelBrokerUrl, resolveTunnelRegistrationSecret } from "../../tunnel/env.js";
|
|
7
8
|
import { loadTunnelState } from "../../tunnel/tunnel-state.js";
|
|
8
9
|
import { getTunnelService } from "../../tunnel/tunnel-service.js";
|
|
10
|
+
import { formatExamples, register } from "../registry.js";
|
|
9
11
|
import "../../config/index.js";
|
|
12
|
+
import { resolveGatewayAuth } from "../../gateway/auth.js";
|
|
13
|
+
import { requireTunnelGatewayToken } from "../../tunnel/auth-policy.js";
|
|
10
14
|
import { TUNNEL_RISK_SUMMARY_LINES, TunnelConsentError, assertTunnelMayStart, hasValidTunnelConsent } from "../../tunnel/consent.js";
|
|
11
15
|
import { resolveFrpSubdomainHost } from "../../tunnel/frp-subdomain-host.js";
|
|
12
16
|
import { applyTunnelConsentToConfig, mergeTunnelConfigPatch, setTunnelEnabledInConfig } from "../../tunnel/tunnel-config.js";
|
|
13
|
-
import { formatExamples, register } from "../registry.js";
|
|
14
17
|
import "../../tunnel/index.js";
|
|
15
18
|
import { Command } from "commander";
|
|
16
19
|
//#region src/cli/commands/tunnel.ts
|
|
@@ -26,6 +29,7 @@ function resolveGatewayPortHost(config) {
|
|
|
26
29
|
};
|
|
27
30
|
}
|
|
28
31
|
function resolveGatewayToken(config) {
|
|
32
|
+
requireTunnelGatewayToken(resolveGatewayAuth({ authConfig: config.gateway.auth }));
|
|
29
33
|
const fromEnv = process.env.XOPC_GATEWAY_TOKEN?.trim();
|
|
30
34
|
if (fromEnv) return fromEnv;
|
|
31
35
|
const token = config.gateway.auth?.token?.trim();
|
|
@@ -155,6 +159,7 @@ function createTunnelCommand(ctx) {
|
|
|
155
159
|
});
|
|
156
160
|
const config = loadConfig(ctx.configPath);
|
|
157
161
|
assertTunnelMayStart(config);
|
|
162
|
+
if (!isXopcDatabaseOpen()) openXopcDatabase();
|
|
158
163
|
const { port, host } = resolveGatewayPortHost(config);
|
|
159
164
|
const token = resolveGatewayToken(config);
|
|
160
165
|
const tunnel = getTunnelService();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { PACKAGE_VERSION, init_package_version } from "../../package-version.js";
|
|
2
2
|
import { loadConfig } from "../../config/loader.js";
|
|
3
|
+
import { formatExamples, register } from "../registry.js";
|
|
3
4
|
import "../../config/index.js";
|
|
4
5
|
import { acquireUpdateLock } from "../../infra/update-lock.js";
|
|
5
6
|
import { normalizeUpdateChannel } from "../../infra/update-channels.js";
|
|
6
7
|
import { compareSemver, resolveNpmChannelTag } from "../../infra/update-check.js";
|
|
7
8
|
import { formatUpdateApiResult, resolveUpdateInstallSurface, runGatewayUpdateWithPostSteps } from "../../infra/update-runner.js";
|
|
8
|
-
import { formatExamples, register } from "../registry.js";
|
|
9
9
|
import { Command } from "commander";
|
|
10
10
|
//#region src/cli/commands/update.ts
|
|
11
11
|
init_package_version();
|
|
@@ -4,9 +4,9 @@ import { ExtensionLoader } from "../extensions/loader.js";
|
|
|
4
4
|
import "../extensions/index.js";
|
|
5
5
|
import { MessageBus } from "../infra/bus/queue.js";
|
|
6
6
|
import "../infra/bus/index.js";
|
|
7
|
+
import { createDefaultContext } from "./registry.js";
|
|
7
8
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
8
9
|
import "../config/index.js";
|
|
9
|
-
import { createDefaultContext } from "./registry.js";
|
|
10
10
|
import { registerExtensionCliProgram } from "../extensions/sdk/channel-helpers.js";
|
|
11
11
|
import { join } from "path";
|
|
12
12
|
//#region src/cli/extension-cli-register.ts
|
package/dist/src/config/index.js
CHANGED
|
@@ -13,10 +13,10 @@ import { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_
|
|
|
13
13
|
import { CustomModelSchema, ImageGenerationCapabilitiesSchema, ImageGenerationModelSchema, ImageGenerationProviderSchema, ModelOverrideSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProviderConfigSchema, VercelGatewayRoutingSchema, getDefaultModelValues, init_models_json, loadModelsJson, modelsJsonExists, saveModelsJson, validateModelsConfig } from "./models-json.js";
|
|
14
14
|
import { canonicalizeConfiguredMcpServer, isKnownCliMcpTypeAlias, normalizeConfiguredMcpServers, resolveXopcMcpTransportAlias } from "./mcp-config-normalize.js";
|
|
15
15
|
import { formatThinkingLevels, listThinkingLevels, normalizeElevatedMode, normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel, thinkLevelToNumber } from "../agent/transcript/thinking-types.js";
|
|
16
|
-
import { diffConfigPaths } from "./diff.js";
|
|
17
16
|
import { getWorkspacePath } from "./workspace-path-helpers.js";
|
|
18
17
|
import { listAgentProfileMarkdownDirs, listAgentWorkspaceDirs } from "./workspace-dirs.js";
|
|
19
18
|
import { ProfileManager, createProfile, deleteProfile, getCurrentProfile, getProfileManager, getProfileNameFromDir, getSwitchCommand, listProfiles, resolveProfileStateDir } from "./profile.js";
|
|
19
|
+
import { diffConfigPaths } from "./diff.js";
|
|
20
20
|
import { BASE_RELOAD_RULES, buildReloadPlan, matchReloadRule } from "./rules.js";
|
|
21
21
|
import { ConfigHotReloader } from "./reload.js";
|
|
22
22
|
//#region src/config/index.ts
|
|
@@ -19,9 +19,6 @@ function routeId(kind, url) {
|
|
|
19
19
|
function resolveSecureDeviceRoutes(config) {
|
|
20
20
|
const tunnelStatus = getTunnelService().getStatus();
|
|
21
21
|
const candidates = [{
|
|
22
|
-
kind: "custom-https",
|
|
23
|
-
url: secureUrl(resolveReverseProxyPublicUrl(config))
|
|
24
|
-
}, {
|
|
25
22
|
kind: "xopc-secure-link",
|
|
26
23
|
url: tunnelStatus.state === "connected" ? secureUrl(tunnelStatus.publicUrl) : null
|
|
27
24
|
}];
|
|
@@ -30,6 +27,10 @@ function resolveSecureDeviceRoutes(config) {
|
|
|
30
27
|
kind: "tailscale",
|
|
31
28
|
url: secureUrl(`https://${tailscale.hostname}`)
|
|
32
29
|
});
|
|
30
|
+
candidates.push({
|
|
31
|
+
kind: "custom-https",
|
|
32
|
+
url: secureUrl(resolveReverseProxyPublicUrl(config))
|
|
33
|
+
});
|
|
33
34
|
const seen = /* @__PURE__ */ new Set();
|
|
34
35
|
const routes = [];
|
|
35
36
|
for (const candidate of candidates) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
|
|
4
|
+
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
4
5
|
import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
|
|
5
6
|
import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
|
|
6
|
-
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
7
7
|
import { createHeartbeatWake } from "../../heartbeat/wake.js";
|
|
8
8
|
import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
|
|
9
9
|
import { readFile } from "fs/promises";
|
|
@@ -225,6 +225,7 @@ function createHonoApp(config) {
|
|
|
225
225
|
authenticated.use(auth({
|
|
226
226
|
getGatewayAuth: () => service.currentConfig.gateway?.auth,
|
|
227
227
|
getResolvedAuth: () => service.getResolvedAuth(),
|
|
228
|
+
isPublicTunnelEnabled: () => service.currentConfig.tunnel?.enabled === true,
|
|
228
229
|
getTrustedProxyContext: () => ({
|
|
229
230
|
trustedProxies: service.currentConfig.gateway?.trustedProxies,
|
|
230
231
|
allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true
|
|
@@ -4,13 +4,12 @@ export interface AuthConfig {
|
|
|
4
4
|
/** Current gateway auth from config (for rate-limit settings); optional. */
|
|
5
5
|
getGatewayAuth?: () => GatewayAuthConfig | undefined;
|
|
6
6
|
getResolvedAuth?: () => ResolvedGatewayAuth;
|
|
7
|
+
isPublicTunnelEnabled?: () => boolean;
|
|
7
8
|
getTrustedProxyContext?: () => {
|
|
8
9
|
trustedProxies?: string[];
|
|
9
10
|
allowRealIpFallback?: boolean;
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
|
-
/** Exported for gateway security tests. */
|
|
13
|
-
export declare function isQueryTokenAllowedPath(path: string, method: string): boolean;
|
|
14
13
|
export declare function auth(config?: AuthConfig): import("hono").MiddlewareHandler<any, string, {}, (Response & import("hono").TypedResponse<{
|
|
15
14
|
error: string;
|
|
16
15
|
code: string;
|
|
@@ -5,11 +5,12 @@ import { authenticateDeviceAccessToken, getDevice } from "../../../storage/sqlit
|
|
|
5
5
|
import { safeEqualSecret } from "../../security/secret-equal.js";
|
|
6
6
|
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
7
7
|
import { authPolicyConfig, buckets, resolveAuthRateLimit } from "../../rate-limit/buckets.js";
|
|
8
|
-
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
9
8
|
import { resolveAuthTracking } from "../../rate-limit/auth-policy.js";
|
|
10
9
|
import { isAuthRateLimitGloballyDisabled } from "../../rate-limit/env-flags.js";
|
|
11
10
|
import "../../rate-limit/index.js";
|
|
11
|
+
import { authenticateBrowserSession } from "../../../storage/sqlite/browser-session-repository.js";
|
|
12
12
|
import { isChromeExtensionOrigin } from "../../security/origin-check.js";
|
|
13
|
+
import { browserCookieRequestAllowed, readBrowserSessionCookie, writeBrowserSessionCookie } from "../../security/browser-session.js";
|
|
13
14
|
import { authorizeTrustedProxy } from "../../trusted-proxy.js";
|
|
14
15
|
import { setGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
15
16
|
import { createMiddleware } from "hono/factory";
|
|
@@ -30,21 +31,6 @@ function extractTokenFromHeader(authHeader) {
|
|
|
30
31
|
if (parts.length === 2 && parts[0].toLowerCase() === "bearer") return parts[1];
|
|
31
32
|
return authHeader;
|
|
32
33
|
}
|
|
33
|
-
/**
|
|
34
|
-
* SECURITY: query-string tokens leak into server logs, Referer headers, and
|
|
35
|
-
* browser history. We accept them only for avatar `<img>` loads, where an
|
|
36
|
-
* Authorization header cannot be set. Realtime WebSocket authentication uses a
|
|
37
|
-
* one-time ticket acquired over authenticated HTTP.
|
|
38
|
-
*/
|
|
39
|
-
function extractTokenFromQuery(url) {
|
|
40
|
-
return new URL(url).searchParams.get("token");
|
|
41
|
-
}
|
|
42
|
-
const AGENT_AVATAR_GET_PATH = /^\/api\/agents\/[^/]+\/avatar$/;
|
|
43
|
-
/** Exported for gateway security tests. */
|
|
44
|
-
function isQueryTokenAllowedPath(path, method) {
|
|
45
|
-
if (method === "GET" && AGENT_AVATAR_GET_PATH.test(path)) return true;
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
34
|
function resolveRemoteAddress(c) {
|
|
49
35
|
try {
|
|
50
36
|
return getConnInfo(c).remote.address;
|
|
@@ -53,17 +39,16 @@ function resolveRemoteAddress(c) {
|
|
|
53
39
|
}
|
|
54
40
|
}
|
|
55
41
|
function resolveMiddlewareClientIp(c, trustedProxies, allowRealIpFallback) {
|
|
56
|
-
|
|
42
|
+
return resolveClientIpFromRequest({
|
|
57
43
|
remoteAddress: resolveRemoteAddress(c),
|
|
58
44
|
getHeader: (name) => c.req.header(name),
|
|
59
45
|
trustedProxies,
|
|
60
46
|
allowRealIpFallback
|
|
61
47
|
});
|
|
62
|
-
return getClientIpFromHeaders({ get: (name) => c.req.header(name) ?? void 0 });
|
|
63
48
|
}
|
|
64
|
-
function buildRateLimitContext(getGatewayAuth, clientIp, origin) {
|
|
49
|
+
function buildRateLimitContext(getGatewayAuth, clientIp, origin, enforce = false) {
|
|
65
50
|
const cfg = resolveAuthRateLimit(getGatewayAuth?.()?.rateLimit);
|
|
66
|
-
if (!(cfg.enabled && !isAuthRateLimitGloballyDisabled())) return {
|
|
51
|
+
if (!(cfg.enabled && (enforce || !isAuthRateLimitGloballyDisabled()))) return {
|
|
67
52
|
active: false,
|
|
68
53
|
cfg,
|
|
69
54
|
trackingKey: void 0
|
|
@@ -101,7 +86,18 @@ function blockedResponse(c, retryAfterSec) {
|
|
|
101
86
|
}, 429);
|
|
102
87
|
}
|
|
103
88
|
function auth(config) {
|
|
104
|
-
const { getGatewayAuth, getResolvedAuth, getTrustedProxyContext } = config || {};
|
|
89
|
+
const { getGatewayAuth: readGatewayAuth, getResolvedAuth, getTrustedProxyContext, isPublicTunnelEnabled } = config || {};
|
|
90
|
+
const getGatewayAuth = () => {
|
|
91
|
+
const current = readGatewayAuth?.();
|
|
92
|
+
return isPublicTunnelEnabled?.() ? {
|
|
93
|
+
...current,
|
|
94
|
+
rateLimit: {
|
|
95
|
+
...current?.rateLimit,
|
|
96
|
+
enabled: true,
|
|
97
|
+
exemptLoopback: false
|
|
98
|
+
}
|
|
99
|
+
} : current;
|
|
100
|
+
};
|
|
105
101
|
return createMiddleware(async (c, next) => {
|
|
106
102
|
const resolvedAuth = getResolvedAuth?.();
|
|
107
103
|
if (!resolvedAuth) {
|
|
@@ -115,13 +111,17 @@ function auth(config) {
|
|
|
115
111
|
}, 401);
|
|
116
112
|
}
|
|
117
113
|
const authMode = resolvedAuth.mode;
|
|
114
|
+
if (isPublicTunnelEnabled?.() && authMode !== "token") return c.json({
|
|
115
|
+
error: "Unauthorized",
|
|
116
|
+
code: "unsafe_tunnel_auth"
|
|
117
|
+
}, 401);
|
|
118
118
|
if (authMode === "trusted-proxy") {
|
|
119
119
|
const proxyContext = getTrustedProxyContext?.();
|
|
120
120
|
const trustedProxies = proxyContext?.trustedProxies;
|
|
121
121
|
const trustedProxyConfig = resolvedAuth?.trustedProxy;
|
|
122
122
|
const clientIp = resolveMiddlewareClientIp(c, trustedProxies, proxyContext?.allowRealIpFallback);
|
|
123
123
|
const origin = c.req.header("origin");
|
|
124
|
-
const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin);
|
|
124
|
+
const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin, isPublicTunnelEnabled?.());
|
|
125
125
|
if (!trustedProxyConfig) {
|
|
126
126
|
log.warn({
|
|
127
127
|
path: c.req.path,
|
|
@@ -199,16 +199,34 @@ function auth(config) {
|
|
|
199
199
|
const proxyContext = getTrustedProxyContext?.();
|
|
200
200
|
const clientIp = resolveMiddlewareClientIp(c, proxyContext?.trustedProxies, proxyContext?.allowRealIpFallback);
|
|
201
201
|
const origin = c.req.header("origin");
|
|
202
|
-
const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin);
|
|
202
|
+
const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin, isPublicTunnelEnabled?.());
|
|
203
203
|
const authHeader = extractTokenFromHeader(c.req.header("authorization"));
|
|
204
|
+
const browserCookie = readBrowserSessionCookie(c);
|
|
205
|
+
if (!authHeader && browserCookie) {
|
|
206
|
+
if (!browserCookieRequestAllowed(c)) return c.json({
|
|
207
|
+
error: "Forbidden",
|
|
208
|
+
code: "csrf_rejected"
|
|
209
|
+
}, 403);
|
|
210
|
+
const session = authenticateBrowserSession(browserCookie, resolvedAuth);
|
|
211
|
+
if (!session) {
|
|
212
|
+
recordFailure(rl);
|
|
213
|
+
return c.json({
|
|
214
|
+
error: "Unauthorized",
|
|
215
|
+
code: "browser_session_expired"
|
|
216
|
+
}, 401);
|
|
217
|
+
}
|
|
218
|
+
if (session.renewed) writeBrowserSessionCookie(c, browserCookie, session.expiresAt);
|
|
219
|
+
setGatewayPrincipal(c, {
|
|
220
|
+
kind: "owner",
|
|
221
|
+
principalId: `browser:${session.sessionId}`,
|
|
222
|
+
browserSessionId: session.sessionId,
|
|
223
|
+
scopes: ["gateway.admin"]
|
|
224
|
+
});
|
|
225
|
+
recordSuccess(rl);
|
|
226
|
+
return next();
|
|
227
|
+
}
|
|
204
228
|
const requestPath = new URL(c.req.url).pathname;
|
|
205
|
-
const
|
|
206
|
-
if (!authHeader && queryToken === null && new URL(c.req.url).searchParams.has("token")) log.warn({
|
|
207
|
-
path: requestPath,
|
|
208
|
-
method: c.req.method,
|
|
209
|
-
clientIp
|
|
210
|
-
}, "Credential in query string rejected: use Authorization header for this endpoint");
|
|
211
|
-
const providedCredential = authHeader || queryToken;
|
|
229
|
+
const providedCredential = authHeader;
|
|
212
230
|
const browserExtensionOrigin = isChromeExtensionOrigin(origin) ? origin.toLowerCase() : void 0;
|
|
213
231
|
if (providedCredential && validateCredential(providedCredential, expectedCredential)) {
|
|
214
232
|
if (browserExtensionOrigin) return c.json({
|
|
@@ -294,4 +312,4 @@ function auth(config) {
|
|
|
294
312
|
});
|
|
295
313
|
}
|
|
296
314
|
//#endregion
|
|
297
|
-
export { auth
|
|
315
|
+
export { auth };
|
|
@@ -2,7 +2,6 @@ import { createLogger } from "../../../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
3
|
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
4
4
|
import { buckets } from "../../rate-limit/buckets.js";
|
|
5
|
-
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
6
5
|
import "../../rate-limit/index.js";
|
|
7
6
|
import { createMiddleware } from "hono/factory";
|
|
8
7
|
import { getConnInfo } from "@hono/node-server/conninfo";
|
|
@@ -15,21 +14,18 @@ init_logger();
|
|
|
15
14
|
const log = createLogger("Hono:StrictRateLimit");
|
|
16
15
|
function resolveClientIp(c, deps) {
|
|
17
16
|
const { trustedProxies, allowRealIpFallback } = deps.getTrustedProxyContext();
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
remoteAddress = void 0;
|
|
24
|
-
}
|
|
25
|
-
return resolveClientIpFromRequest({
|
|
26
|
-
remoteAddress,
|
|
27
|
-
getHeader: (name) => c.req.header(name),
|
|
28
|
-
trustedProxies,
|
|
29
|
-
allowRealIpFallback
|
|
30
|
-
});
|
|
17
|
+
let remoteAddress;
|
|
18
|
+
try {
|
|
19
|
+
remoteAddress = getConnInfo(c).remote.address;
|
|
20
|
+
} catch {
|
|
21
|
+
remoteAddress = void 0;
|
|
31
22
|
}
|
|
32
|
-
return
|
|
23
|
+
return resolveClientIpFromRequest({
|
|
24
|
+
remoteAddress,
|
|
25
|
+
getHeader: (name) => c.req.header(name),
|
|
26
|
+
trustedProxies,
|
|
27
|
+
allowRealIpFallback
|
|
28
|
+
});
|
|
33
29
|
}
|
|
34
30
|
function createClientRateLimitMiddleware(deps, options) {
|
|
35
31
|
return createMiddleware(async (c, next) => {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BrowserSessionLimitError, createBrowserSession, deleteBrowserSession } from "../../../storage/sqlite/browser-session-repository.js";
|
|
2
|
+
import { browserCookieRequestAllowed, clearBrowserSessionCookie, writeBrowserSessionCookie } from "../../security/browser-session.js";
|
|
3
|
+
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
4
|
+
//#region src/gateway/hono/routes/browser-session.ts
|
|
5
|
+
function registerBrowserSessionRoutes(app, deps) {
|
|
6
|
+
app.get("/api/browser-session", (c) => {
|
|
7
|
+
c.header("Cache-Control", "no-store");
|
|
8
|
+
const principal = getGatewayPrincipal(c);
|
|
9
|
+
return c.json({ sessionKey: principal.principalId });
|
|
10
|
+
});
|
|
11
|
+
app.post("/api/browser-session", deps.strictRateLimitMiddleware, (c) => {
|
|
12
|
+
const principal = getGatewayPrincipal(c);
|
|
13
|
+
if (principal.kind !== "owner" || !browserCookieRequestAllowed(c)) return c.json({ error: "Forbidden" }, 403);
|
|
14
|
+
let session;
|
|
15
|
+
try {
|
|
16
|
+
session = createBrowserSession(deps.service.getResolvedAuth(), principal.browserSessionId);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error instanceof BrowserSessionLimitError) return c.json({ error: "Browser session limit reached" }, 409);
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
if (principal.browserSessionId) {
|
|
22
|
+
deps.service.realtime.disconnectPrincipal(principal.principalId);
|
|
23
|
+
deps.service.voiceRealtime.disconnectPrincipal(principal.principalId);
|
|
24
|
+
}
|
|
25
|
+
writeBrowserSessionCookie(c, session.token, session.expiresAt);
|
|
26
|
+
c.header("Cache-Control", "no-store");
|
|
27
|
+
return c.json({ sessionKey: `browser:${session.sessionId}` });
|
|
28
|
+
});
|
|
29
|
+
app.delete("/api/browser-session", (c) => {
|
|
30
|
+
if (!browserCookieRequestAllowed(c)) return c.json({ error: "Forbidden" }, 403);
|
|
31
|
+
const principal = getGatewayPrincipal(c);
|
|
32
|
+
if (principal.browserSessionId) {
|
|
33
|
+
deleteBrowserSession(principal.browserSessionId);
|
|
34
|
+
deps.service.realtime.disconnectPrincipal(principal.principalId);
|
|
35
|
+
deps.service.voiceRealtime.disconnectPrincipal(principal.principalId);
|
|
36
|
+
}
|
|
37
|
+
clearBrowserSessionCookie(c);
|
|
38
|
+
c.header("Cache-Control", "no-store");
|
|
39
|
+
return c.json({ ok: true });
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { registerBrowserSessionRoutes };
|