@xopcai/xopc 0.0.230 → 0.0.232
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 -0
- package/README.zh-CN.md +1 -0
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/schema/config-schema.d.ts +3 -3
- package/dist/extensions/telegram/src/config-schema.d.ts +4 -4
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/config-schema.d.ts +3 -3
- package/dist/gateway/static/root/assets/{activity-store-M0nAY5XB.js → activity-store-VXCWz43N.js} +1 -1
- package/dist/gateway/static/root/assets/agent-avatar-dicebear-BXRaZYW8.js +1 -0
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-dR7HMaRX.js +1 -0
- package/dist/gateway/static/root/assets/agents-Bileycwe.js +1 -0
- package/dist/gateway/static/root/assets/api-wGPgL8xY.js +1 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-CwAPK4Jm.js → app-management-settings-panel-BJfClfPx.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DsGLvqTb.js → appearance-settings-C_R0vUAu.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-Ee9qOQEx.js → apps-page-CBow8pBI.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-7_DXaMTP.js → archive-plugin-DnFHkSHE.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-B4qqigAQ.js → attachment-load-DZrEwytM.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-B8ImehSW.js → automations-page-DpkKajui.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BBntVWgv.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DaJbyYc2.js → binary-plugins-Ckc_Csue.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Kl25XWJc.js → block-editor-DAC6w-iV.js} +4 -4
- package/dist/gateway/static/root/assets/browser-settings-page-DrsMd-Po.js +8 -0
- package/dist/gateway/static/root/assets/browser-workflow-inputs-BGd7R8GO.js +1 -0
- package/dist/gateway/static/root/assets/{browser-workflows-page-DjMxs33B.js → browser-workflows-page-DUfj7ntM.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-97gkGeSV.js +7 -0
- package/dist/gateway/static/root/assets/channels-settings-CuBsz8UI.js +1 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-C5ABr73b.js → channels-status-swr-CfboECLt.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BiU_4Rq6.js → chat-terminal-dock-CA9fndbZ.js} +2 -2
- package/dist/gateway/static/root/assets/cloud-C4-yfnnk.js +1 -0
- package/dist/gateway/static/root/assets/{code-editor-dFzqyDXS.js → code-editor-D4_k-6QN.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-SuL7td7Z.js +2 -0
- package/dist/gateway/static/root/assets/cron-expression-CqPu7HYJ.js +2 -0
- package/dist/gateway/static/root/assets/date-picker-C8dJsCgk.js +1 -0
- package/dist/gateway/static/root/assets/dependency-picker-Iz2wYimy.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-ux9DxchT.js → desktop-pet-C3h40FmG.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BVVCBgYK.js → desktop-pet-settings-YfeVVzLe.js} +1 -1
- package/dist/gateway/static/root/assets/dist-DqPZM2MH2.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Dh6DDuvQ.js → extension-debug-page-CChgztz_.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-8OKQDEat.js → extension-page-DF6ct6_y.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-jgBsjn0F.js +1 -0
- package/dist/gateway/static/root/assets/files-Dp8_uGTO.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-api-Dlc6eaTG.js → gateway-config-api-CVajuIGL.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-config-swr-BGQn8duh.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-settings-DqQgiAUv.js → gateway-settings-BbssNGid.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-B_zrtccP.js → gateway-startup-retry-D2Rnh9fX.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CJtXu8iD.js +1 -0
- package/dist/gateway/static/root/assets/home-page-Be1o1AXQ.js +1 -0
- package/dist/gateway/static/root/assets/html-workspace-editor-C3DKAkMc.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-YKP2me5Z.js → image-generation-api-D7W2p5_8.js} +1 -1
- package/dist/gateway/static/root/assets/index-B2OJSXX9.js +70 -0
- package/dist/gateway/static/root/assets/index-rHjAElxG.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BSFNqxzY.js → keyboard-shortcuts-settings-BvHYyNus.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-COfelgk7.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-DzU6yZ9-.js → local-apps-page-Cb8t2wWM.js} +1 -1
- package/dist/gateway/static/root/assets/locale-store-DLwVxS3V.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-DA8oDjeB.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-B8Jie4-J.js +1 -0
- package/dist/gateway/static/root/assets/markdown-editor-nDLmA_LF.js +2 -0
- package/dist/gateway/static/root/assets/markdown-split-BD1r4o2i.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-DvM5PWEH.js → markdown-view-B-BHEcNd.js} +1 -1
- package/dist/gateway/static/root/assets/markdown-view-B1bGSQqt.css +1 -0
- package/dist/gateway/static/root/assets/{media-plugins-B8vMe5VX.js → media-plugins-BCev8fkW.js} +1 -1
- package/dist/gateway/static/root/assets/messages-Dp1OxSKt.js +3 -0
- package/dist/gateway/static/root/assets/mobile-device-api-DACoHhhk.js +1 -0
- package/dist/gateway/static/root/assets/models-hub-cache-C8zjqmIv.js +1 -0
- package/dist/gateway/static/root/assets/{notes-api-BFsOGYkd.js → notes-api-DEdNKw0I.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-B-YZ7iuK.js → notes-page-BBTLjJwa.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-DICgUGPv.js +4 -0
- package/dist/gateway/static/root/assets/oauth-api-BNCO2YK5.js +1 -0
- package/dist/gateway/static/root/assets/popover-select-3E24E65N.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-DkWcyki5.js → product-open-page-fEBbRekH.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-CqdkznYJ.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-dHDXpMCg.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BFZrVYfy.js → registry-api-Cvr4Qm7N.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-2feZudJw.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Bq_ETeal.js → runtime-tools-settings-panel-BT5B74IH.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-BogTlrsP.js → schema-form-C4tB34S5.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CO2JCFdy.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DxMVaqdn.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-Coy1Cbp6.js → settings-form-section-D1oXhkgI.js} +1 -1
- package/dist/gateway/static/root/assets/settings-loading-skeleton-CldfX6FJ.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-c3LJnbvE.js +1 -0
- package/dist/gateway/static/root/assets/settings-shell-layer-context-DCp6ykjQ.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-DZNHb6A5.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-DptCK_mk.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-DakZ2AGN.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BOiNkWJC.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-Brxb6QnW.js → skills-page-OHBeBtSg.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-FB5LtEGm.js → skills-page.utils-B9WZbOLC.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-ChosWt8n.js → system-settings-panel-Dj_DpOGw.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-D5Nbe3C8.js +1 -0
- package/dist/gateway/static/root/assets/theme-store-Cpd3Gd5R.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-2SqnmSKD.js → use-autosave-DCl5Yq7N.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-CAPSUK8B.js +1 -0
- package/dist/gateway/static/root/assets/{vendor-codemirror-DRr7hFaD.js → vendor-codemirror--gTq3YAI.js} +16 -16
- package/dist/gateway/static/root/assets/voice-api-key-field-BB_ZQV8F.js +1 -0
- package/dist/gateway/static/root/assets/voice-config-api-BNiYmpl5.js +1 -0
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CK3aZDdE.js → work-discovery-overlay-BrIdtdum.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BjOuddkX.js → workflow-run-setup-panel-hKh-uCLo.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-ahDvypGO.js +5 -0
- package/dist/gateway/static/root/index.html +19 -15
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +1 -2
- package/dist/src/agent/agent-manager.js +29 -44
- package/dist/src/agent/background-review/run-background-review.js +10 -15
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/external-tools/mcp-provider.js +3 -13
- package/dist/src/agent/image/generation/runtime.js +1 -1
- package/dist/src/agent/image/tool-model-config.js +13 -14
- package/dist/src/agent/mcp/bundle-mcp-policy.d.ts +0 -9
- package/dist/src/agent/mcp/bundle-mcp-policy.js +1 -13
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
- package/dist/src/agent/mcp/index.js +2 -2
- package/dist/src/agent/media-generation/runtime-shared.d.ts +1 -1
- package/dist/src/agent/media-generation/runtime-shared.js +1 -1
- package/dist/src/agent/memory/create-memory-manager.js +1 -1
- package/dist/src/agent/memory/manager.d.ts +1 -1
- package/dist/src/{agent-runtime/memory-runtime.d.ts → agent/memory/runtime.d.ts} +1 -1
- package/dist/src/{agent-runtime/memory-runtime.js → agent/memory/runtime.js} +2 -3
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -3
- package/dist/src/agent/orchestration/agent-orchestrator.js +1 -3
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +2 -2
- package/dist/src/agent/service.d.ts +1 -0
- package/dist/src/agent/service.js +5 -3
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/starter-agents.js +1 -8
- package/dist/src/agent/tools/executor.d.ts +1 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -5
- package/dist/src/agent/tools/write.js +9 -12
- package/dist/src/agent/tools/xopc-use-tool.js +2 -2
- package/dist/src/agent-config/index.d.ts +2 -0
- package/dist/src/agent-config/index.js +11 -0
- package/dist/src/agent-config/resolver.d.ts +11 -0
- package/dist/src/agent-config/resolver.js +113 -0
- package/dist/src/agent-config/schema.d.ts +491 -0
- package/dist/src/agent-config/schema.js +172 -0
- package/dist/src/auth/oauth/index.js +2 -2
- package/dist/src/auth/oauth/registry.d.ts +1 -1
- package/dist/src/auth/oauth/registry.js +5 -1
- package/dist/src/auth/oauth/xopc-cloud.d.ts +1 -0
- package/dist/src/auth/oauth/xopc-cloud.js +8 -2
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/builtins/review.js +1 -1
- package/dist/src/chat-commands/config-paths.js +1 -1
- package/dist/src/cli/commands/agents.js +2 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +12 -4
- package/dist/src/cli/commands/image.js +3 -4
- package/dist/src/cli/commands/models.js +9 -3
- package/dist/src/cli/commands/onboard/model.js +12 -11
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/tunnel.js +3 -18
- package/dist/src/cli/utils/init-workspace-core.d.ts +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +1 -1
- package/dist/src/commands/agents.config.d.ts +1 -3
- package/dist/src/commands/agents.config.js +9 -26
- package/dist/src/config/agent-model-intents.d.ts +10 -0
- package/dist/src/config/agent-model-intents.js +39 -0
- package/dist/src/config/agent-profile.d.ts +7 -9
- package/dist/src/config/agent-profile.js +30 -28
- package/dist/src/config/default-model.d.ts +1 -11
- package/dist/src/config/default-model.js +3 -11
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/integration.d.ts +1 -1
- package/dist/src/config/reload.js +1 -1
- package/dist/src/config/rules.js +3 -3
- package/dist/src/config/schema.d.ts +187 -452
- package/dist/src/config/schema.js +53 -131
- package/dist/src/extensions/activation-context.js +7 -11
- package/dist/src/files/file-service.d.ts +36 -0
- package/dist/src/files/file-service.js +282 -0
- package/dist/src/gateway/agent-builtin-tools.d.ts +250 -6
- package/dist/src/gateway/agent-builtin-tools.js +284 -46
- package/dist/src/gateway/agents-admin.d.ts +20 -62
- package/dist/src/gateway/agents-admin.js +36 -228
- package/dist/src/gateway/device-routes.d.ts +3 -0
- package/dist/src/gateway/device-routes.js +47 -0
- package/dist/src/gateway/global-defaults-admin.d.ts +6 -20
- package/dist/src/gateway/global-defaults-admin.js +20 -120
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/app.js +6 -4
- package/dist/src/gateway/hono/lib/config-payload.d.ts +54 -137
- package/dist/src/gateway/hono/lib/config-payload.js +2 -4
- package/dist/src/gateway/hono/middleware/auth.js +33 -1
- package/dist/src/gateway/hono/middleware/scopes.d.ts +2 -12
- package/dist/src/gateway/hono/middleware/scopes.js +9 -18
- package/dist/src/gateway/hono/routes/agents.js +64 -100
- package/dist/src/gateway/hono/routes/connectors.js +1 -1
- package/dist/src/gateway/hono/routes/device-push.d.ts +2 -0
- package/dist/src/gateway/hono/routes/{mobile.js → device-push.js} +40 -18
- package/dist/src/gateway/hono/routes/devices.d.ts +4 -0
- package/dist/src/gateway/hono/routes/devices.js +214 -0
- package/dist/src/gateway/hono/routes/files.d.ts +3 -0
- package/dist/src/gateway/hono/routes/files.js +176 -0
- package/dist/src/gateway/hono/routes/global-defaults.js +5 -9
- package/dist/src/gateway/hono/routes/index.js +4 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +12 -20
- package/dist/src/gateway/hono/routes/models.js +2 -2
- package/dist/src/gateway/hono/routes/projects.js +0 -508
- package/dist/src/gateway/hono/routes/realtime.js +8 -1
- package/dist/src/gateway/hono/routes/shares.js +410 -21
- package/dist/src/gateway/hono/routes/status.js +9 -16
- package/dist/src/gateway/hono/routes/tunnel.d.ts +0 -2
- package/dist/src/gateway/hono/routes/tunnel.js +10 -199
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +15 -974
- package/dist/src/gateway/image-generation-setup.d.ts +2 -2
- package/dist/src/gateway/image-generation-setup.js +8 -7
- package/dist/src/gateway/public-url.d.ts +1 -1
- package/dist/src/gateway/security/gateway-principal.d.ts +11 -0
- package/dist/src/gateway/security/gateway-principal.js +12 -0
- package/dist/src/gateway/security/gateway-scopes.d.ts +7 -0
- package/dist/src/gateway/security/gateway-scopes.js +66 -0
- package/dist/src/gateway/security/index.d.ts +2 -1
- package/dist/src/gateway/security/index.js +3 -2
- package/dist/src/gateway/service.js +4 -4
- package/dist/src/gateway/xopc-cloud-capability-setup.js +19 -21
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/migrations/index.d.ts +0 -1
- package/dist/src/migrations/index.js +1 -2
- package/dist/src/migrations/runner.js +1 -2
- package/dist/src/notifications/device-store.d.ts +1 -1
- package/dist/src/notifications/device-store.js +11 -11
- package/dist/src/notifications/store.js +3 -3
- package/dist/src/providers/index.js +1 -1
- package/dist/src/providers/model-reference-auditor.js +14 -9
- package/dist/src/realtime/runtime.d.ts +2 -0
- package/dist/src/realtime/runtime.js +27 -3
- package/dist/src/realtime/tickets.d.ts +6 -1
- package/dist/src/realtime/tickets.js +2 -1
- package/dist/src/remote-access/exposure-manager.js +3 -3
- package/dist/src/share/hosted-session-share.d.ts +104 -0
- package/dist/src/share/hosted-session-share.js +276 -0
- package/dist/src/share/note-share-service.js +4 -24
- package/dist/src/share/session-share-projector.d.ts +31 -0
- package/dist/src/share/session-share-projector.js +79 -0
- package/dist/src/share/session-share-service.d.ts +89 -0
- package/dist/src/share/session-share-service.js +325 -0
- package/dist/src/share/share-asset-ticket.d.ts +7 -0
- package/dist/src/share/share-asset-ticket.js +30 -0
- package/dist/src/share/share-landing.d.ts +4 -3
- package/dist/src/share/share-landing.js +5 -5
- package/dist/src/share/share-store.d.ts +27 -2
- package/dist/src/share/share-store.js +71 -8
- package/dist/src/share/share-types.d.ts +17 -2
- package/dist/src/share/share-url.js +2 -2
- package/dist/src/storage/sqlite/device-access-repository.d.ts +54 -0
- package/dist/src/storage/sqlite/device-access-repository.js +194 -0
- package/dist/src/storage/sqlite/device-pairing-repository.d.ts +22 -0
- package/dist/src/storage/sqlite/device-pairing-repository.js +86 -0
- package/dist/src/storage/sqlite/gateway-identity-repository.d.ts +10 -0
- package/dist/src/storage/sqlite/gateway-identity-repository.js +50 -0
- package/dist/src/storage/sqlite/index.d.ts +3 -0
- package/dist/src/storage/sqlite/index.js +4 -1
- package/dist/src/storage/sqlite/migrations/138_device_access.sql +96 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tui/backends/gateway-realtime-backend.js +11 -3
- package/dist/src/tunnel/consent.d.ts +1 -1
- package/dist/src/tunnel/consent.js +1 -1
- package/dist/src/tunnel/gateway-lifecycle.js +1 -1
- package/dist/src/tunnel/index.d.ts +1 -4
- package/dist/src/tunnel/index.js +3 -5
- package/dist/src/tunnel/tunnel-audit.d.ts +1 -1
- package/dist/src/tunnel/tunnel-config.js +1 -1
- package/dist/src/tunnel/tunnel-service.d.ts +2 -3
- package/dist/src/tunnel/tunnel-service.js +1 -20
- package/dist/src/tunnel/tunnel-types.d.ts +0 -6
- package/dist/src/workflows/draft/workflow-draft-service.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.js +3 -3
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/agent-avatar-dicebear-Bp_wmuGW.js +0 -1
- package/dist/gateway/static/root/assets/agents-CKG93dlc.js +0 -68
- package/dist/gateway/static/root/assets/api-BywYxpaS.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-BNFAfNwC.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-Cg6NgwE_.js +0 -8
- package/dist/gateway/static/root/assets/browser-workflow-inputs-8NC2qDRF.js +0 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-NvJKgF1u.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-api-o0y9WgAI.js +0 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-C2uBdALe.js +0 -3
- package/dist/gateway/static/root/assets/channels-settings-CIcYKMEs.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-38FsOnR0.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CEEcmUiP.js +0 -2
- package/dist/gateway/static/root/assets/cron-expression-Cs_5pUPT.js +0 -2
- package/dist/gateway/static/root/assets/date-picker-y1kWrFVU.js +0 -1
- package/dist/gateway/static/root/assets/dependency-picker-skc62zrn.js +0 -1
- package/dist/gateway/static/root/assets/directory-picker-path-field-V8vZP0Dy.js +0 -1
- package/dist/gateway/static/root/assets/dist-J_ySZvz0.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BgSV0Nny.js +0 -1
- package/dist/gateway/static/root/assets/file-code-corner-byQA1VfD.js +0 -1
- package/dist/gateway/static/root/assets/gateway-config-swr-BWGjnmDl.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-Pxqk5GFH.js +0 -1
- package/dist/gateway/static/root/assets/home-page-1xjo6wE4.js +0 -1
- package/dist/gateway/static/root/assets/html-workspace-editor-bXK5tq64.js +0 -1
- package/dist/gateway/static/root/assets/index-Bbd_dXui.js +0 -70
- package/dist/gateway/static/root/assets/index-D_hrEKXM.css +0 -2
- package/dist/gateway/static/root/assets/local-app-workbench-page-heQ4-PJ7.js +0 -2
- package/dist/gateway/static/root/assets/locale-store-CXhjfe4q.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-BblnS6Jy.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-B8hM56HS.js +0 -1
- package/dist/gateway/static/root/assets/markdown-editor-TWGaF7Xa.js +0 -2
- package/dist/gateway/static/root/assets/markdown-split-DRbZjxMK.js +0 -1
- package/dist/gateway/static/root/assets/markdown-view-CLzTdVLW.css +0 -1
- package/dist/gateway/static/root/assets/messages-BMdD0LWk.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-CAM09C8b.js +0 -4
- package/dist/gateway/static/root/assets/popover-select-CccGri5Y.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-BIPIwgU2.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-B_kzTn1K.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CtD8DsD-.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-B8n9HI1y.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-xlhdRTME.js +0 -1
- package/dist/gateway/static/root/assets/settings-loading-skeleton-B5GU7iCG.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-Dd-BRu12.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CwEFAVWx.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-DzXw9UQJ.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-Bk6UQOwS.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DrmQZ3Au.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-CW2sJbdc.js +0 -1
- package/dist/gateway/static/root/assets/theme-store-DOdCjyuw.js +0 -1
- package/dist/gateway/static/root/assets/typed-models-lib-q5-Vfqd8.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-Bq9KB-Oj.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-DtTIF6M8.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-CcbGEQol.js +0 -5
- package/dist/src/agent-manifest/index.d.ts +0 -5
- package/dist/src/agent-manifest/index.js +0 -10
- package/dist/src/agent-manifest/preset-chain.d.ts +0 -10
- package/dist/src/agent-manifest/preset-chain.js +0 -30
- package/dist/src/agent-manifest/prompt.d.ts +0 -2
- package/dist/src/agent-manifest/prompt.js +0 -49
- package/dist/src/agent-manifest/resolver.d.ts +0 -32
- package/dist/src/agent-manifest/resolver.js +0 -114
- package/dist/src/agent-manifest/schema.d.ts +0 -695
- package/dist/src/agent-manifest/schema.js +0 -226
- package/dist/src/agent-manifest/validator.d.ts +0 -25
- package/dist/src/agent-manifest/validator.js +0 -74
- package/dist/src/agent-runtime/boundary-guard.d.ts +0 -12
- package/dist/src/agent-runtime/boundary-guard.js +0 -21
- package/dist/src/agent-runtime/index.d.ts +0 -7
- package/dist/src/agent-runtime/index.js +0 -8
- package/dist/src/agent-runtime/model-router.d.ts +0 -11
- package/dist/src/agent-runtime/model-router.js +0 -14
- package/dist/src/agent-runtime/run-trace.d.ts +0 -27
- package/dist/src/agent-runtime/run-trace.js +0 -51
- package/dist/src/agent-runtime/runtime-profile.d.ts +0 -26
- package/dist/src/agent-runtime/runtime-profile.js +0 -42
- package/dist/src/agent-runtime/tool-registry.d.ts +0 -28
- package/dist/src/agent-runtime/tool-registry.js +0 -50
- package/dist/src/agent-runtime/workflow-runtime.d.ts +0 -31
- package/dist/src/agent-runtime/workflow-runtime.js +0 -32
- package/dist/src/config/agent-typed-models.d.ts +0 -13
- package/dist/src/config/agent-typed-models.js +0 -48
- package/dist/src/gateway/capability-presets-admin.d.ts +0 -88
- package/dist/src/gateway/capability-presets-admin.js +0 -303
- package/dist/src/gateway/file-path-classifier.d.ts +0 -30
- package/dist/src/gateway/file-path-classifier.js +0 -105
- package/dist/src/gateway/file-reference-errors.d.ts +0 -6
- package/dist/src/gateway/file-reference-errors.js +0 -21
- package/dist/src/gateway/file-reference-registry.d.ts +0 -34
- package/dist/src/gateway/file-reference-registry.js +0 -45
- package/dist/src/gateway/hono/lib/agent-model.d.ts +0 -35
- package/dist/src/gateway/hono/lib/agent-model.js +0 -97
- package/dist/src/gateway/hono/routes/capability-presets.d.ts +0 -3
- package/dist/src/gateway/hono/routes/capability-presets.js +0 -187
- package/dist/src/gateway/hono/routes/mobile.d.ts +0 -3
- package/dist/src/gateway/security/operator-scopes.d.ts +0 -37
- package/dist/src/gateway/security/operator-scopes.js +0 -147
- package/dist/src/migrations/config/default-capability-preset.d.ts +0 -10
- package/dist/src/migrations/config/default-capability-preset.js +0 -133
- package/dist/src/tunnel/enable-lan-pairing.d.ts +0 -8
- package/dist/src/tunnel/enable-lan-pairing.js +0 -41
- package/dist/src/tunnel/pair-context.d.ts +0 -36
- package/dist/src/tunnel/pair-context.js +0 -77
- package/dist/src/tunnel/pair-url.d.ts +0 -43
- package/dist/src/tunnel/pair-url.js +0 -117
- package/dist/src/tunnel/pairing-rate-limit.d.ts +0 -12
- package/dist/src/tunnel/pairing-rate-limit.js +0 -28
- package/dist/src/tunnel/pairing.d.ts +0 -21
- package/dist/src/tunnel/pairing.js +0 -103
- package/dist/src/tunnel/tunnel-qr.d.ts +0 -9
- package/dist/src/tunnel/tunnel-qr.js +0 -29
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import type { GatewayScope } from '../../gateway/security/gateway-scopes.js';
|
|
3
|
+
export type DevicePlatform = 'ios' | 'android';
|
|
4
|
+
export type DevicePublicKeyJwk = crypto.webcrypto.JsonWebKey;
|
|
5
|
+
export type DeviceRecord = {
|
|
6
|
+
id: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
platform: DevicePlatform;
|
|
9
|
+
publicKeyJwk: DevicePublicKeyJwk;
|
|
10
|
+
scopes: GatewayScope[];
|
|
11
|
+
createdAt: number;
|
|
12
|
+
lastSeenAt?: number;
|
|
13
|
+
revokedAt?: number;
|
|
14
|
+
};
|
|
15
|
+
export type DeviceAccessIdentity = {
|
|
16
|
+
deviceId: string;
|
|
17
|
+
accessSessionId: string;
|
|
18
|
+
scopes: GatewayScope[];
|
|
19
|
+
};
|
|
20
|
+
export type DeviceTokenPair = {
|
|
21
|
+
accessToken: string;
|
|
22
|
+
accessTokenExpiresAt: number;
|
|
23
|
+
refreshToken: string;
|
|
24
|
+
refreshTokenExpiresAt: number;
|
|
25
|
+
};
|
|
26
|
+
export declare function createDevice(input: {
|
|
27
|
+
id?: string;
|
|
28
|
+
displayName: string;
|
|
29
|
+
platform: DevicePlatform;
|
|
30
|
+
publicKeyJwk: DevicePublicKeyJwk;
|
|
31
|
+
scopes: readonly GatewayScope[];
|
|
32
|
+
now?: number;
|
|
33
|
+
}): DeviceRecord;
|
|
34
|
+
export declare function getDevice(deviceId: string): DeviceRecord | undefined;
|
|
35
|
+
export declare function listDevices(): DeviceRecord[];
|
|
36
|
+
export declare function issueDeviceTokenPair(deviceId: string, now?: number): DeviceTokenPair;
|
|
37
|
+
export declare function authenticateDeviceAccessToken(token: string, now?: number): DeviceAccessIdentity | undefined;
|
|
38
|
+
export declare function buildRefreshProofMessage(input: {
|
|
39
|
+
credentialId: string;
|
|
40
|
+
timestamp: number;
|
|
41
|
+
nonce: string;
|
|
42
|
+
requestId: string;
|
|
43
|
+
nextRefreshToken: string;
|
|
44
|
+
}): string;
|
|
45
|
+
export declare function rotateDeviceRefreshToken(input: {
|
|
46
|
+
refreshToken: string;
|
|
47
|
+
timestamp: number;
|
|
48
|
+
nonce: string;
|
|
49
|
+
requestId: string;
|
|
50
|
+
nextRefreshToken: string;
|
|
51
|
+
signature: string;
|
|
52
|
+
now?: number;
|
|
53
|
+
}): DeviceTokenPair;
|
|
54
|
+
export declare function revokeDevice(deviceId: string, now?: number): boolean;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
+
import { parseGatewayScopes } from "../../gateway/security/gateway-scopes.js";
|
|
3
|
+
import crypto from "node:crypto";
|
|
4
|
+
//#region src/storage/sqlite/device-access-repository.ts
|
|
5
|
+
const ACCESS_TOKEN_TTL_MS = 900 * 1e3;
|
|
6
|
+
const REFRESH_TOKEN_TTL_MS = 2160 * 60 * 60 * 1e3;
|
|
7
|
+
const REFRESH_PROOF_MAX_AGE_MS = 300 * 1e3;
|
|
8
|
+
const ACCESS_TOKEN_PREFIX = "xopc_at_";
|
|
9
|
+
const REFRESH_TOKEN_PREFIX = "xopc_rt_";
|
|
10
|
+
function tokenHash(token) {
|
|
11
|
+
return crypto.createHash("sha256").update(token).digest("hex");
|
|
12
|
+
}
|
|
13
|
+
function buildToken(prefix, id) {
|
|
14
|
+
return `${prefix}${id}_${crypto.randomBytes(32).toString("base64url")}`;
|
|
15
|
+
}
|
|
16
|
+
function parseToken(token, prefix) {
|
|
17
|
+
if (!token.startsWith(prefix)) return void 0;
|
|
18
|
+
const separator = token.indexOf("_", prefix.length);
|
|
19
|
+
if (separator <= prefix.length || separator === token.length - 1) return void 0;
|
|
20
|
+
return { id: token.slice(prefix.length, separator) };
|
|
21
|
+
}
|
|
22
|
+
function deviceFromRow(row) {
|
|
23
|
+
return {
|
|
24
|
+
id: row.device_id,
|
|
25
|
+
displayName: row.display_name,
|
|
26
|
+
platform: row.platform,
|
|
27
|
+
publicKeyJwk: JSON.parse(row.public_key_jwk),
|
|
28
|
+
scopes: parseGatewayScopes(row.scopes_json),
|
|
29
|
+
createdAt: row.created_at,
|
|
30
|
+
...row.last_seen_at === null ? {} : { lastSeenAt: row.last_seen_at },
|
|
31
|
+
...row.revoked_at === null ? {} : { revokedAt: row.revoked_at }
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function createDevice(input) {
|
|
35
|
+
const id = input.id ?? crypto.randomUUID();
|
|
36
|
+
const createdAt = input.now ?? Date.now();
|
|
37
|
+
getSqliteDatabase().prepare(`
|
|
38
|
+
INSERT INTO devices (
|
|
39
|
+
device_id, display_name, platform, public_key_jwk, scopes_json, created_at
|
|
40
|
+
) VALUES (?, ?, ?, ?, ?, ?)
|
|
41
|
+
`).run(id, input.displayName, input.platform, JSON.stringify(input.publicKeyJwk), JSON.stringify([...new Set(input.scopes)]), createdAt);
|
|
42
|
+
return getDevice(id);
|
|
43
|
+
}
|
|
44
|
+
function getDevice(deviceId) {
|
|
45
|
+
const row = getSqliteDatabase().prepare("SELECT * FROM devices WHERE device_id = ?").get(deviceId);
|
|
46
|
+
return row ? deviceFromRow(row) : void 0;
|
|
47
|
+
}
|
|
48
|
+
function listDevices() {
|
|
49
|
+
return getSqliteDatabase().prepare("SELECT * FROM devices ORDER BY created_at DESC").all().map(deviceFromRow);
|
|
50
|
+
}
|
|
51
|
+
function issueAccessToken(deviceId, now) {
|
|
52
|
+
const accessSessionId = crypto.randomUUID();
|
|
53
|
+
const accessToken = buildToken(ACCESS_TOKEN_PREFIX, accessSessionId);
|
|
54
|
+
const accessTokenExpiresAt = now + ACCESS_TOKEN_TTL_MS;
|
|
55
|
+
getSqliteDatabase().prepare(`
|
|
56
|
+
INSERT INTO device_access_sessions (
|
|
57
|
+
session_id, device_id, token_hash, expires_at, created_at
|
|
58
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
59
|
+
`).run(accessSessionId, deviceId, tokenHash(accessToken), accessTokenExpiresAt, now);
|
|
60
|
+
return {
|
|
61
|
+
accessToken,
|
|
62
|
+
accessTokenExpiresAt
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function issueDeviceTokenPair(deviceId, now = Date.now()) {
|
|
66
|
+
const device = getDevice(deviceId);
|
|
67
|
+
if (!device || device.revokedAt !== void 0) throw new Error("Device is unavailable");
|
|
68
|
+
const refreshCredentialId = crypto.randomUUID();
|
|
69
|
+
const refreshToken = buildToken(REFRESH_TOKEN_PREFIX, refreshCredentialId);
|
|
70
|
+
const refreshTokenExpiresAt = now + REFRESH_TOKEN_TTL_MS;
|
|
71
|
+
return {
|
|
72
|
+
...runSqliteWriteTransaction((db) => {
|
|
73
|
+
const issuedAccess = issueAccessToken(deviceId, now);
|
|
74
|
+
db.prepare(`
|
|
75
|
+
INSERT INTO device_refresh_credentials (
|
|
76
|
+
credential_id, device_id, token_hash, expires_at, created_at
|
|
77
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
78
|
+
`).run(refreshCredentialId, deviceId, tokenHash(refreshToken), refreshTokenExpiresAt, now);
|
|
79
|
+
return issuedAccess;
|
|
80
|
+
}),
|
|
81
|
+
refreshToken,
|
|
82
|
+
refreshTokenExpiresAt
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function authenticateDeviceAccessToken(token, now = Date.now()) {
|
|
86
|
+
const parsed = parseToken(token, ACCESS_TOKEN_PREFIX);
|
|
87
|
+
if (!parsed) return void 0;
|
|
88
|
+
const row = getSqliteDatabase().prepare(`
|
|
89
|
+
SELECT a.session_id, a.device_id, a.token_hash, a.expires_at, a.revoked_at,
|
|
90
|
+
d.scopes_json, d.revoked_at AS device_revoked_at
|
|
91
|
+
FROM device_access_sessions a
|
|
92
|
+
JOIN devices d ON d.device_id = a.device_id
|
|
93
|
+
WHERE a.session_id = ?
|
|
94
|
+
`).get(parsed.id);
|
|
95
|
+
if (!row || row.expires_at <= now || row.revoked_at !== null || row.device_revoked_at !== null || !crypto.timingSafeEqual(Buffer.from(row.token_hash, "hex"), Buffer.from(tokenHash(token), "hex"))) return;
|
|
96
|
+
getSqliteDatabase().prepare("UPDATE devices SET last_seen_at = ? WHERE device_id = ?").run(now, row.device_id);
|
|
97
|
+
return {
|
|
98
|
+
deviceId: row.device_id,
|
|
99
|
+
accessSessionId: row.session_id,
|
|
100
|
+
scopes: parseGatewayScopes(row.scopes_json)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function buildRefreshProofMessage(input) {
|
|
104
|
+
return `xopc-device-refresh-v2\n${input.credentialId}\n${input.timestamp}\n${input.nonce}\n${input.requestId}\n${input.nextRefreshToken}`;
|
|
105
|
+
}
|
|
106
|
+
function verifyRefreshProof(publicKeyJwk, message, signature) {
|
|
107
|
+
try {
|
|
108
|
+
const publicKey = crypto.createPublicKey({
|
|
109
|
+
key: publicKeyJwk,
|
|
110
|
+
format: "jwk"
|
|
111
|
+
});
|
|
112
|
+
return crypto.verify("sha256", Buffer.from(message), {
|
|
113
|
+
key: publicKey,
|
|
114
|
+
dsaEncoding: "ieee-p1363"
|
|
115
|
+
}, Buffer.from(signature, "base64url"));
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function rotateDeviceRefreshToken(input) {
|
|
121
|
+
const now = input.now ?? Date.now();
|
|
122
|
+
const parsed = parseToken(input.refreshToken, REFRESH_TOKEN_PREFIX);
|
|
123
|
+
const nextParsed = parseToken(input.nextRefreshToken, REFRESH_TOKEN_PREFIX);
|
|
124
|
+
if (!parsed || !nextParsed || parsed.id === nextParsed.id) throw new Error("Invalid refresh credential");
|
|
125
|
+
if (Math.abs(now - input.timestamp) > REFRESH_PROOF_MAX_AGE_MS) throw new Error("Refresh proof expired");
|
|
126
|
+
const result = runSqliteWriteTransaction((db) => {
|
|
127
|
+
const credential = db.prepare(`
|
|
128
|
+
SELECT credential_id, device_id, token_hash, expires_at, replaced_by,
|
|
129
|
+
rotation_request_id, revoked_at
|
|
130
|
+
FROM device_refresh_credentials WHERE credential_id = ?
|
|
131
|
+
`).get(parsed.id);
|
|
132
|
+
const suppliedHash = tokenHash(input.refreshToken);
|
|
133
|
+
if (!credential || credential.token_hash !== suppliedHash) throw new Error("Invalid refresh credential");
|
|
134
|
+
const deviceRow = db.prepare("SELECT * FROM devices WHERE device_id = ?").get(credential.device_id);
|
|
135
|
+
if (!deviceRow || deviceRow.revoked_at !== null) throw new Error("Device is unavailable");
|
|
136
|
+
const message = buildRefreshProofMessage({
|
|
137
|
+
credentialId: credential.credential_id,
|
|
138
|
+
timestamp: input.timestamp,
|
|
139
|
+
nonce: input.nonce,
|
|
140
|
+
requestId: input.requestId,
|
|
141
|
+
nextRefreshToken: input.nextRefreshToken
|
|
142
|
+
});
|
|
143
|
+
if (!verifyRefreshProof(JSON.parse(deviceRow.public_key_jwk), message, input.signature)) throw new Error("Invalid refresh proof");
|
|
144
|
+
if (credential.replaced_by === nextParsed.id && credential.rotation_request_id === input.requestId) {
|
|
145
|
+
const nextCredential = db.prepare(`
|
|
146
|
+
SELECT credential_id, device_id, token_hash, expires_at, replaced_by,
|
|
147
|
+
rotation_request_id, revoked_at
|
|
148
|
+
FROM device_refresh_credentials WHERE credential_id = ?
|
|
149
|
+
`).get(nextParsed.id);
|
|
150
|
+
if (nextCredential?.token_hash === tokenHash(input.nextRefreshToken)) return {
|
|
151
|
+
...issueAccessToken(credential.device_id, now),
|
|
152
|
+
refreshToken: input.nextRefreshToken,
|
|
153
|
+
refreshTokenExpiresAt: nextCredential.expires_at
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
if (credential.replaced_by !== null || credential.revoked_at !== null) {
|
|
157
|
+
db.prepare("UPDATE devices SET revoked_at = ? WHERE device_id = ? AND revoked_at IS NULL").run(now, credential.device_id);
|
|
158
|
+
db.prepare("UPDATE device_access_sessions SET revoked_at = ? WHERE device_id = ? AND revoked_at IS NULL").run(now, credential.device_id);
|
|
159
|
+
db.prepare("UPDATE device_refresh_credentials SET revoked_at = ? WHERE device_id = ? AND revoked_at IS NULL").run(now, credential.device_id);
|
|
160
|
+
return "reused";
|
|
161
|
+
}
|
|
162
|
+
if (credential.expires_at <= now) throw new Error("Refresh credential expired");
|
|
163
|
+
const access = issueAccessToken(credential.device_id, now);
|
|
164
|
+
const refreshTokenExpiresAt = now + REFRESH_TOKEN_TTL_MS;
|
|
165
|
+
db.prepare(`
|
|
166
|
+
INSERT INTO device_refresh_credentials (
|
|
167
|
+
credential_id, device_id, token_hash, expires_at, created_at
|
|
168
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
169
|
+
`).run(nextParsed.id, credential.device_id, tokenHash(input.nextRefreshToken), refreshTokenExpiresAt, now);
|
|
170
|
+
db.prepare(`
|
|
171
|
+
UPDATE device_refresh_credentials
|
|
172
|
+
SET last_used_at = ?, replaced_by = ?, rotation_request_id = ?, revoked_at = ?
|
|
173
|
+
WHERE credential_id = ?
|
|
174
|
+
`).run(now, nextParsed.id, input.requestId, now, credential.credential_id);
|
|
175
|
+
return {
|
|
176
|
+
...access,
|
|
177
|
+
refreshToken: input.nextRefreshToken,
|
|
178
|
+
refreshTokenExpiresAt
|
|
179
|
+
};
|
|
180
|
+
});
|
|
181
|
+
if (result === "reused") throw new Error("Refresh credential reuse detected");
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
function revokeDevice(deviceId, now = Date.now()) {
|
|
185
|
+
return runSqliteWriteTransaction((db) => {
|
|
186
|
+
const changed = db.prepare("UPDATE devices SET revoked_at = ? WHERE device_id = ? AND revoked_at IS NULL").run(now, deviceId).changes > 0;
|
|
187
|
+
db.prepare("UPDATE device_access_sessions SET revoked_at = ? WHERE device_id = ? AND revoked_at IS NULL").run(now, deviceId);
|
|
188
|
+
db.prepare("UPDATE device_refresh_credentials SET revoked_at = ? WHERE device_id = ? AND revoked_at IS NULL").run(now, deviceId);
|
|
189
|
+
db.prepare("DELETE FROM device_push_endpoints WHERE device_id = ?").run(deviceId);
|
|
190
|
+
return changed;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
//#endregion
|
|
194
|
+
export { authenticateDeviceAccessToken, buildRefreshProofMessage, createDevice, getDevice, issueDeviceTokenPair, listDevices, revokeDevice, rotateDeviceRefreshToken };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type DeviceRoute = {
|
|
2
|
+
id: string;
|
|
3
|
+
kind: 'xopc-secure-link' | 'tailscale' | 'custom-https';
|
|
4
|
+
url: string;
|
|
5
|
+
};
|
|
6
|
+
export type DevicePairingSetup = {
|
|
7
|
+
id: string;
|
|
8
|
+
token: string;
|
|
9
|
+
routes: DeviceRoute[];
|
|
10
|
+
expiresAt: number;
|
|
11
|
+
};
|
|
12
|
+
export type PairingConsumeResult = {
|
|
13
|
+
ok: true;
|
|
14
|
+
pairingId: string;
|
|
15
|
+
routes: DeviceRoute[];
|
|
16
|
+
} | {
|
|
17
|
+
ok: false;
|
|
18
|
+
reason: 'invalid' | 'expired' | 'consumed';
|
|
19
|
+
};
|
|
20
|
+
export declare function createDevicePairingSetup(routes: readonly DeviceRoute[], now?: number): DevicePairingSetup;
|
|
21
|
+
export declare function consumeDevicePairingToken(token: string, now?: number): PairingConsumeResult;
|
|
22
|
+
export declare function isDevicePairingSetupActive(pairingId: string, now?: number): boolean;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
//#region src/storage/sqlite/device-pairing-repository.ts
|
|
4
|
+
const PAIRING_TOKEN_PREFIX = "xopc_pair_";
|
|
5
|
+
const PAIRING_TTL_MS = 600 * 1e3;
|
|
6
|
+
const PAIRING_ATTEMPTS = 5;
|
|
7
|
+
function hashToken(token) {
|
|
8
|
+
return crypto.createHash("sha256").update(token).digest("hex");
|
|
9
|
+
}
|
|
10
|
+
function hashesMatch(left, right) {
|
|
11
|
+
return crypto.timingSafeEqual(Buffer.from(left, "hex"), Buffer.from(right, "hex"));
|
|
12
|
+
}
|
|
13
|
+
function tokenId(token) {
|
|
14
|
+
if (!token.startsWith(PAIRING_TOKEN_PREFIX)) return void 0;
|
|
15
|
+
const separator = token.indexOf("_", 10);
|
|
16
|
+
if (separator <= 10 || separator === token.length - 1) return void 0;
|
|
17
|
+
return token.slice(10, separator);
|
|
18
|
+
}
|
|
19
|
+
function createDevicePairingSetup(routes, now = Date.now()) {
|
|
20
|
+
if (routes.length === 0) throw new Error("No secure mobile route is available");
|
|
21
|
+
const id = crypto.randomUUID();
|
|
22
|
+
const token = `${PAIRING_TOKEN_PREFIX}${id}_${crypto.randomBytes(32).toString("base64url")}`;
|
|
23
|
+
const expiresAt = now + PAIRING_TTL_MS;
|
|
24
|
+
runSqliteWriteTransaction((db) => {
|
|
25
|
+
db.prepare("DELETE FROM device_pairing_sessions WHERE expires_at <= ? OR consumed_at IS NOT NULL").run(now);
|
|
26
|
+
db.prepare(`
|
|
27
|
+
INSERT INTO device_pairing_sessions (
|
|
28
|
+
pairing_id, secret_hash, routes_json, expires_at, attempts_remaining, created_at
|
|
29
|
+
) VALUES (?, ?, ?, ?, ?, ?)
|
|
30
|
+
`).run(id, hashToken(token), JSON.stringify(routes), expiresAt, PAIRING_ATTEMPTS, now);
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
id,
|
|
34
|
+
token,
|
|
35
|
+
routes: [...routes],
|
|
36
|
+
expiresAt
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function consumeDevicePairingToken(token, now = Date.now()) {
|
|
40
|
+
const id = tokenId(token);
|
|
41
|
+
if (!id) return {
|
|
42
|
+
ok: false,
|
|
43
|
+
reason: "invalid"
|
|
44
|
+
};
|
|
45
|
+
return runSqliteWriteTransaction((db) => {
|
|
46
|
+
const row = db.prepare("SELECT * FROM device_pairing_sessions WHERE pairing_id = ?").get(id);
|
|
47
|
+
if (!row || row.attempts_remaining <= 0) return {
|
|
48
|
+
ok: false,
|
|
49
|
+
reason: "invalid"
|
|
50
|
+
};
|
|
51
|
+
if (row.consumed_at !== null) return {
|
|
52
|
+
ok: false,
|
|
53
|
+
reason: "consumed"
|
|
54
|
+
};
|
|
55
|
+
if (row.expires_at <= now) return {
|
|
56
|
+
ok: false,
|
|
57
|
+
reason: "expired"
|
|
58
|
+
};
|
|
59
|
+
if (!hashesMatch(row.secret_hash, hashToken(token))) {
|
|
60
|
+
db.prepare(`
|
|
61
|
+
UPDATE device_pairing_sessions
|
|
62
|
+
SET attempts_remaining = attempts_remaining - 1
|
|
63
|
+
WHERE pairing_id = ? AND attempts_remaining > 0
|
|
64
|
+
`).run(id);
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
reason: "invalid"
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
db.prepare("UPDATE device_pairing_sessions SET consumed_at = ? WHERE pairing_id = ?").run(now, id);
|
|
71
|
+
return {
|
|
72
|
+
ok: true,
|
|
73
|
+
pairingId: id,
|
|
74
|
+
routes: JSON.parse(row.routes_json)
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function isDevicePairingSetupActive(pairingId, now = Date.now()) {
|
|
79
|
+
const row = getSqliteDatabase().prepare(`
|
|
80
|
+
SELECT 1 FROM device_pairing_sessions
|
|
81
|
+
WHERE pairing_id = ? AND expires_at > ? AND consumed_at IS NULL AND attempts_remaining > 0
|
|
82
|
+
`).get(pairingId, now);
|
|
83
|
+
return Boolean(row);
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { consumeDevicePairingToken, createDevicePairingSetup, isDevicePairingSetupActive };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type GatewayIdentity = {
|
|
2
|
+
id: string;
|
|
3
|
+
publicKey: string;
|
|
4
|
+
privateKey: string;
|
|
5
|
+
createdAt: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function getOrCreateGatewayIdentity(now?: number): GatewayIdentity;
|
|
8
|
+
export declare function signGatewayPayload(payload: string): string;
|
|
9
|
+
export declare function getGatewayIdentityPublicKeyRaw(identity?: GatewayIdentity): string;
|
|
10
|
+
export declare function clearGatewayIdentityForTest(): void;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
//#region src/storage/sqlite/gateway-identity-repository.ts
|
|
4
|
+
function fromRow(row) {
|
|
5
|
+
return {
|
|
6
|
+
id: row.gateway_id,
|
|
7
|
+
publicKey: row.public_key,
|
|
8
|
+
privateKey: row.private_key,
|
|
9
|
+
createdAt: row.created_at
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function getOrCreateGatewayIdentity(now = Date.now()) {
|
|
13
|
+
return runSqliteWriteTransaction((db) => {
|
|
14
|
+
const existing = db.prepare("SELECT * FROM gateway_identity WHERE singleton_id = 1").get();
|
|
15
|
+
if (existing) return fromRow(existing);
|
|
16
|
+
const keys = crypto.generateKeyPairSync("ed25519");
|
|
17
|
+
const identity = {
|
|
18
|
+
id: crypto.randomUUID(),
|
|
19
|
+
publicKey: keys.publicKey.export({
|
|
20
|
+
type: "spki",
|
|
21
|
+
format: "pem"
|
|
22
|
+
}).toString(),
|
|
23
|
+
privateKey: keys.privateKey.export({
|
|
24
|
+
type: "pkcs8",
|
|
25
|
+
format: "pem"
|
|
26
|
+
}).toString(),
|
|
27
|
+
createdAt: now
|
|
28
|
+
};
|
|
29
|
+
db.prepare(`
|
|
30
|
+
INSERT INTO gateway_identity (
|
|
31
|
+
singleton_id, gateway_id, public_key, private_key, created_at
|
|
32
|
+
) VALUES (1, ?, ?, ?, ?)
|
|
33
|
+
`).run(identity.id, identity.publicKey, identity.privateKey, identity.createdAt);
|
|
34
|
+
return identity;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function signGatewayPayload(payload) {
|
|
38
|
+
const identity = getOrCreateGatewayIdentity();
|
|
39
|
+
return crypto.sign(null, Buffer.from(payload), identity.privateKey).toString("base64url");
|
|
40
|
+
}
|
|
41
|
+
function getGatewayIdentityPublicKeyRaw(identity = getOrCreateGatewayIdentity()) {
|
|
42
|
+
const jwk = crypto.createPublicKey(identity.publicKey).export({ format: "jwk" });
|
|
43
|
+
if (typeof jwk.x !== "string") throw new Error("Gateway identity public key is invalid");
|
|
44
|
+
return jwk.x;
|
|
45
|
+
}
|
|
46
|
+
function clearGatewayIdentityForTest() {
|
|
47
|
+
getSqliteDatabase().prepare("DELETE FROM gateway_identity").run();
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { clearGatewayIdentityForTest, getGatewayIdentityPublicKeyRaw, getOrCreateGatewayIdentity, signGatewayPayload };
|
|
@@ -5,6 +5,9 @@ export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, } from './m
|
|
|
5
5
|
export { discoverSqlMigrations, listRegisteredMigrationTargets } from './migrations/discover.js';
|
|
6
6
|
export { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest, type OpenXopcDatabaseOptions, type XopcDatabase, } from './connection.js';
|
|
7
7
|
export { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';
|
|
8
|
+
export { authenticateDeviceAccessToken, buildRefreshProofMessage, createDevice, getDevice, issueDeviceTokenPair, listDevices, revokeDevice, rotateDeviceRefreshToken, type DeviceAccessIdentity, type DevicePlatform, type DevicePublicKeyJwk, type DeviceRecord, type DeviceTokenPair, } from './device-access-repository.js';
|
|
9
|
+
export { clearGatewayIdentityForTest, getOrCreateGatewayIdentity, signGatewayPayload, type GatewayIdentity, } from './gateway-identity-repository.js';
|
|
10
|
+
export { consumeDevicePairingToken, createDevicePairingSetup, isDevicePairingSetupActive, type DevicePairingSetup, type DeviceRoute, type PairingConsumeResult, } from './device-pairing-repository.js';
|
|
8
11
|
export { claimContextExtractionRun, finishContextExtractionRun, getContextExtractionRun, hasIndependentExtractionOutput, listContextExtractionOutputs, listContextExtractionRuns, type ContextExtractionOutput, type ContextExtractionRun, type ContextExtractionStatus, type ContextObjectType, } from './context-extraction-repository.js';
|
|
9
12
|
export { closeTemporalAssertions, createTemporalAssertion, linkContextObjects, listContextObjectRelations, listTemporalAssertions, type ContextObjectRelation, type ContextTemporalAssertion, } from './context-relation-repository.js';
|
|
10
13
|
export { finishContextConsolidationRun, getContextConsolidationRun, listContextConsolidationDecisions, listContextConsolidationRuns, recordContextConsolidationDecision, startContextConsolidationRun, type ContextConsolidationDecision, type ContextConsolidationRun, } from './context-consolidation-repository.js';
|
|
@@ -6,6 +6,9 @@ import { XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, applyPendingMi
|
|
|
6
6
|
import { ensureXopcDatabaseSchema } from "./schema.js";
|
|
7
7
|
import { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest } from "./connection.js";
|
|
8
8
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
9
|
+
import { authenticateDeviceAccessToken, buildRefreshProofMessage, createDevice, getDevice, issueDeviceTokenPair, listDevices, revokeDevice, rotateDeviceRefreshToken } from "./device-access-repository.js";
|
|
10
|
+
import { clearGatewayIdentityForTest, getOrCreateGatewayIdentity, signGatewayPayload } from "./gateway-identity-repository.js";
|
|
11
|
+
import { consumeDevicePairingToken, createDevicePairingSetup, isDevicePairingSetupActive } from "./device-pairing-repository.js";
|
|
9
12
|
import { claimContextExtractionRun, finishContextExtractionRun, getContextExtractionRun, hasIndependentExtractionOutput, listContextExtractionOutputs, listContextExtractionRuns } from "./context-extraction-repository.js";
|
|
10
13
|
import { closeTemporalAssertions, createTemporalAssertion, linkContextObjects, listContextObjectRelations, listTemporalAssertions } from "./context-relation-repository.js";
|
|
11
14
|
import { finishContextConsolidationRun, getContextConsolidationRun, listContextConsolidationDecisions, listContextConsolidationRuns, recordContextConsolidationDecision, startContextConsolidationRun } from "./context-consolidation-repository.js";
|
|
@@ -36,4 +39,4 @@ import { appendConnectorExecutionAudit, claimConnectorWebhookDelivery, completeC
|
|
|
36
39
|
import { getConnectorAccount, listConnectorAccounts, reconcileConnectorAccount, refreshConnectorAccountCurrent } from "./connector-account-repository.js";
|
|
37
40
|
import { getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, listConnectorSyncPolicies, upsertConnectorSyncPolicy } from "./connector-sync-policy-repository.js";
|
|
38
41
|
import { getUserTrustPolicy, setUserTrustPolicy } from "./user-trust-repository.js";
|
|
39
|
-
export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, acknowledgeHomeAttention, appendCompactionBoundaryIfUnchanged, appendComposerInputHistory, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, bindEndpointPrincipal, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRelationshipPrompt, cancelQueuedSessionInput, claimConnectorWebhookDelivery, claimContextExtractionRun, claimKnowledgeSourceItems, claimNextConnectorLearningJob, claimNextSessionInput, classifyStoredRow, clearComposerInputHistory, closeTemporalAssertions, closeUnderstandingValidity, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeConnectorApproval, consumeContextConsent, countKnowledgeSourceItems, countMemoryRecordsBySourceInstanceId, createCollaborationRule, createConnectorApproval, createContextEvidence, createEndpointPrincipal, createObjectLinkRecord, createTemporalAssertion, createUnderstanding, decideConnectorApproval, decideContextConsent, deleteCollaborationRule, deleteConnectorConnection, deleteConnectorInstallation, deleteKnowledgeSourceItems, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteMemoryRecordsBySourceInstanceId, deleteNoteAgentContextRecord, deleteNoteRecord, deleteObjectLinkRecord, deleteSessionConfig, deleteSessionRecord, deleteUnderstanding, discoverSqlMigrations, enqueueConnectorLearningJob, ensureContextConsent, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findSessionInput, findSessionKeyBySessionId, finishContextConsolidationRun, finishContextExtractionRun, finishEndpointToolInvocationAudit, finishKnowledgeSyncRun, finishSessionInputRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCollaborationRule, getConnectorAccount, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, getContextConsolidationRun, getContextExtractionRun, getCurrentSessionId, getEndpointPrincipal, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getMemoryTurnFeedback, getNoteAgentContextRecord, getNoteRecord, getRelationshipSettings, getSessionConfig, getSessionInputById, getSessionInputState, getSessionMetadata, getSessionPersistedLevels, getSessionTaskPlan, getSqliteDatabase, getTurnPersonalization, getUnderstanding, getUserPeopleIndexState, getUserPerson, getUserProfile, getUserTrustPolicy, getXopcDatabase, hasContextConsent, hasIndependentExtractionOutput, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, insertSessionInput, inspectSchemaMigrationStatus, isHomeAttentionAcknowledged, isProactiveSupportAllowed, isUnderstandingSuppressed, isXopcDatabaseOpen, linkContextObjects, linkUnderstandingEvidence, listActiveSessionInputRuns, listActivityRecords, listCachedConnectorCatalogEntries, listCollaborationRules, listCompactionBoundaries, listComposerInputHistory, listConnectorAccounts, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listConnectorLearningJobs, listConnectorSyncPolicies, listContextConsolidationDecisions, listContextConsolidationRuns, listContextExtractionOutputs, listContextExtractionRuns, listContextObjectRelations, listEndpointPrincipals, listEndpointToolInvocationAudits, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTemporalAssertions, listUnderstandingEvidence, listUnderstandingStatusEvents, listUnderstandings, listUserPeople, loadCompactionSourceSnapshot, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, mergeUserPeople, metadataToSessionInsert, mutateQueuedSessionInput, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, pruneBoundedKnowledgeSourceItems, readSchemaVersion, readSchemaVersionForTest, reconcileConnectorAccount, recordActivityEvent, recordContextConsolidationDecision, recordContextFeedback, recordContextRun, recoverSessionInputState, recoverStaleConnectorLearningJobs, refreshConnectorAccountCurrent, rejectUnderstanding, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceLatestSessionTurnAndQueueInput, replaceTranscriptRows, replaceUserPeopleIndex, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreBeforeCompactionBoundary, reviseCollaborationRule, reviseUnderstanding, revokeEndpointPrincipal, runSqliteWriteTransaction, searchActiveUnderstandings, searchMemoryRecords, searchSessionTranscript, sessionConfigRowToConfig, sessionRowToMetadata, setCollaborationRuleStatus, setConnectorLearningPaused, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setMemoryProviderState, setMemoryRecordStatus, setMemoryTurnFeedback, setSessionConfig, setSessionInputStatus, setSessionTaskPlan, setUnderstandingStatus, setUserTrustPolicy, startContextConsolidationRun, startEndpointToolInvocationAudit, startKnowledgeSyncRun, summarizeMemoryRecallFeedback, summarizeUnderstandingFeedback, summarizeUserPeople, summarizeUserUnderstandingQuality, touchEndpointPrincipal, transcriptEntryRowToStoredRow, updateConnectorLearningJob, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateUserPerson, updateUserProfile, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertConnectorSyncPolicy, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord, validateLatestSessionTurnTarget };
|
|
42
|
+
export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, acknowledgeHomeAttention, appendCompactionBoundaryIfUnchanged, appendComposerInputHistory, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, authenticateDeviceAccessToken, bindEndpointPrincipal, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRefreshProofMessage, buildRelationshipPrompt, cancelQueuedSessionInput, claimConnectorWebhookDelivery, claimContextExtractionRun, claimKnowledgeSourceItems, claimNextConnectorLearningJob, claimNextSessionInput, classifyStoredRow, clearComposerInputHistory, clearGatewayIdentityForTest, closeTemporalAssertions, closeUnderstandingValidity, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeConnectorApproval, consumeContextConsent, consumeDevicePairingToken, countKnowledgeSourceItems, countMemoryRecordsBySourceInstanceId, createCollaborationRule, createConnectorApproval, createContextEvidence, createDevice, createDevicePairingSetup, createEndpointPrincipal, createObjectLinkRecord, createTemporalAssertion, createUnderstanding, decideConnectorApproval, decideContextConsent, deleteCollaborationRule, deleteConnectorConnection, deleteConnectorInstallation, deleteKnowledgeSourceItems, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteMemoryRecordsBySourceInstanceId, deleteNoteAgentContextRecord, deleteNoteRecord, deleteObjectLinkRecord, deleteSessionConfig, deleteSessionRecord, deleteUnderstanding, discoverSqlMigrations, enqueueConnectorLearningJob, ensureContextConsent, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findSessionInput, findSessionKeyBySessionId, finishContextConsolidationRun, finishContextExtractionRun, finishEndpointToolInvocationAudit, finishKnowledgeSyncRun, finishSessionInputRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCollaborationRule, getConnectorAccount, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, getContextConsolidationRun, getContextExtractionRun, getCurrentSessionId, getDevice, getEndpointPrincipal, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getMemoryTurnFeedback, getNoteAgentContextRecord, getNoteRecord, getOrCreateGatewayIdentity, getRelationshipSettings, getSessionConfig, getSessionInputById, getSessionInputState, getSessionMetadata, getSessionPersistedLevels, getSessionTaskPlan, getSqliteDatabase, getTurnPersonalization, getUnderstanding, getUserPeopleIndexState, getUserPerson, getUserProfile, getUserTrustPolicy, getXopcDatabase, hasContextConsent, hasIndependentExtractionOutput, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, insertSessionInput, inspectSchemaMigrationStatus, isDevicePairingSetupActive, isHomeAttentionAcknowledged, isProactiveSupportAllowed, isUnderstandingSuppressed, isXopcDatabaseOpen, issueDeviceTokenPair, linkContextObjects, linkUnderstandingEvidence, listActiveSessionInputRuns, listActivityRecords, listCachedConnectorCatalogEntries, listCollaborationRules, listCompactionBoundaries, listComposerInputHistory, listConnectorAccounts, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listConnectorLearningJobs, listConnectorSyncPolicies, listContextConsolidationDecisions, listContextConsolidationRuns, listContextExtractionOutputs, listContextExtractionRuns, listContextObjectRelations, listDevices, listEndpointPrincipals, listEndpointToolInvocationAudits, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTemporalAssertions, listUnderstandingEvidence, listUnderstandingStatusEvents, listUnderstandings, listUserPeople, loadCompactionSourceSnapshot, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, mergeUserPeople, metadataToSessionInsert, mutateQueuedSessionInput, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, pruneBoundedKnowledgeSourceItems, readSchemaVersion, readSchemaVersionForTest, reconcileConnectorAccount, recordActivityEvent, recordContextConsolidationDecision, recordContextFeedback, recordContextRun, recoverSessionInputState, recoverStaleConnectorLearningJobs, refreshConnectorAccountCurrent, rejectUnderstanding, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceLatestSessionTurnAndQueueInput, replaceTranscriptRows, replaceUserPeopleIndex, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreBeforeCompactionBoundary, reviseCollaborationRule, reviseUnderstanding, revokeDevice, revokeEndpointPrincipal, rotateDeviceRefreshToken, runSqliteWriteTransaction, searchActiveUnderstandings, searchMemoryRecords, searchSessionTranscript, sessionConfigRowToConfig, sessionRowToMetadata, setCollaborationRuleStatus, setConnectorLearningPaused, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setMemoryProviderState, setMemoryRecordStatus, setMemoryTurnFeedback, setSessionConfig, setSessionInputStatus, setSessionTaskPlan, setUnderstandingStatus, setUserTrustPolicy, signGatewayPayload, startContextConsolidationRun, startEndpointToolInvocationAudit, startKnowledgeSyncRun, summarizeMemoryRecallFeedback, summarizeUnderstandingFeedback, summarizeUserPeople, summarizeUserUnderstandingQuality, touchEndpointPrincipal, transcriptEntryRowToStoredRow, updateConnectorLearningJob, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateUserPerson, updateUserProfile, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertConnectorSyncPolicy, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord, validateLatestSessionTurnTarget };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
CREATE TABLE gateway_identity (
|
|
2
|
+
singleton_id INTEGER PRIMARY KEY CHECK (singleton_id = 1),
|
|
3
|
+
gateway_id TEXT NOT NULL UNIQUE,
|
|
4
|
+
public_key TEXT NOT NULL,
|
|
5
|
+
private_key TEXT NOT NULL,
|
|
6
|
+
created_at INTEGER NOT NULL
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
CREATE TABLE devices (
|
|
10
|
+
device_id TEXT PRIMARY KEY,
|
|
11
|
+
display_name TEXT NOT NULL,
|
|
12
|
+
platform TEXT NOT NULL CHECK (platform IN ('ios', 'android')),
|
|
13
|
+
public_key_jwk TEXT NOT NULL,
|
|
14
|
+
scopes_json TEXT NOT NULL,
|
|
15
|
+
created_at INTEGER NOT NULL,
|
|
16
|
+
last_seen_at INTEGER,
|
|
17
|
+
revoked_at INTEGER
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE device_pairing_sessions (
|
|
21
|
+
pairing_id TEXT PRIMARY KEY,
|
|
22
|
+
secret_hash TEXT NOT NULL,
|
|
23
|
+
routes_json TEXT NOT NULL,
|
|
24
|
+
expires_at INTEGER NOT NULL,
|
|
25
|
+
attempts_remaining INTEGER NOT NULL CHECK (attempts_remaining >= 0),
|
|
26
|
+
created_at INTEGER NOT NULL,
|
|
27
|
+
consumed_at INTEGER
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE INDEX idx_device_pairing_sessions_expiry
|
|
31
|
+
ON device_pairing_sessions(expires_at);
|
|
32
|
+
|
|
33
|
+
CREATE TABLE device_refresh_credentials (
|
|
34
|
+
credential_id TEXT PRIMARY KEY,
|
|
35
|
+
device_id TEXT NOT NULL REFERENCES devices(device_id) ON DELETE CASCADE,
|
|
36
|
+
token_hash TEXT NOT NULL,
|
|
37
|
+
expires_at INTEGER NOT NULL,
|
|
38
|
+
created_at INTEGER NOT NULL,
|
|
39
|
+
last_used_at INTEGER,
|
|
40
|
+
replaced_by TEXT REFERENCES device_refresh_credentials(credential_id),
|
|
41
|
+
rotation_request_id TEXT,
|
|
42
|
+
revoked_at INTEGER
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
CREATE INDEX idx_device_refresh_credentials_device
|
|
46
|
+
ON device_refresh_credentials(device_id, expires_at);
|
|
47
|
+
|
|
48
|
+
CREATE TABLE device_access_sessions (
|
|
49
|
+
session_id TEXT PRIMARY KEY,
|
|
50
|
+
device_id TEXT NOT NULL REFERENCES devices(device_id) ON DELETE CASCADE,
|
|
51
|
+
token_hash TEXT NOT NULL,
|
|
52
|
+
expires_at INTEGER NOT NULL,
|
|
53
|
+
created_at INTEGER NOT NULL,
|
|
54
|
+
revoked_at INTEGER
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
CREATE INDEX idx_device_access_sessions_device
|
|
58
|
+
ON device_access_sessions(device_id, expires_at);
|
|
59
|
+
|
|
60
|
+
CREATE TABLE device_push_endpoints (
|
|
61
|
+
device_id TEXT PRIMARY KEY REFERENCES devices(device_id) ON DELETE CASCADE,
|
|
62
|
+
platform TEXT NOT NULL CHECK (platform IN ('ios', 'android')),
|
|
63
|
+
push_token TEXT NOT NULL UNIQUE,
|
|
64
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
65
|
+
permissions TEXT NOT NULL CHECK (permissions IN ('granted', 'denied', 'unknown')),
|
|
66
|
+
preferences_json TEXT NOT NULL DEFAULT '{}',
|
|
67
|
+
locale TEXT NOT NULL CHECK (locale IN ('en', 'zh')),
|
|
68
|
+
app_version TEXT,
|
|
69
|
+
lease_expires_at INTEGER NOT NULL,
|
|
70
|
+
last_seen_at INTEGER NOT NULL,
|
|
71
|
+
created_at INTEGER NOT NULL,
|
|
72
|
+
updated_at INTEGER NOT NULL
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
DROP INDEX idx_notification_deliveries_due;
|
|
76
|
+
ALTER TABLE notification_deliveries RENAME TO obsolete_notification_deliveries;
|
|
77
|
+
|
|
78
|
+
CREATE TABLE notification_deliveries (
|
|
79
|
+
event_id TEXT NOT NULL,
|
|
80
|
+
device_id TEXT NOT NULL,
|
|
81
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'accepted', 'delivered', 'dead')),
|
|
82
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
83
|
+
next_attempt_at INTEGER NOT NULL,
|
|
84
|
+
provider_ticket_id TEXT,
|
|
85
|
+
last_error TEXT,
|
|
86
|
+
updated_at INTEGER NOT NULL,
|
|
87
|
+
PRIMARY KEY (event_id, device_id),
|
|
88
|
+
FOREIGN KEY (event_id) REFERENCES notification_events(event_id) ON DELETE CASCADE,
|
|
89
|
+
FOREIGN KEY (device_id) REFERENCES device_push_endpoints(device_id) ON DELETE CASCADE
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
CREATE INDEX idx_notification_deliveries_due
|
|
93
|
+
ON notification_deliveries(status, next_attempt_at);
|
|
94
|
+
|
|
95
|
+
DROP TABLE obsolete_notification_deliveries;
|
|
96
|
+
DROP TABLE notification_devices;
|
|
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
|
|
|
3
3
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
4
4
|
export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
5
5
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
6
|
-
export declare const XOPC_DB_SCHEMA_VERSION =
|
|
6
|
+
export declare const XOPC_DB_SCHEMA_VERSION = 138;
|
|
7
7
|
export declare function resolveMigrationsDir(override?: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
|
|
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
|
|
|
12
12
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
13
13
|
const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
14
14
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
15
|
-
const XOPC_DB_SCHEMA_VERSION =
|
|
15
|
+
const XOPC_DB_SCHEMA_VERSION = 138;
|
|
16
16
|
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
17
17
|
function backupBeforeTaskCutover(db, databasePath) {
|
|
18
18
|
db.exec("PRAGMA wal_checkpoint(FULL)");
|
|
@@ -57,7 +57,7 @@ function applySingleMigration(db, migration) {
|
|
|
57
57
|
* Each step runs in its own transaction and updates schema_meta on success.
|
|
58
58
|
*/
|
|
59
59
|
function applyPendingMigrations(db, options = {}) {
|
|
60
|
-
const targetVersion = options.targetVersion ??
|
|
60
|
+
const targetVersion = options.targetVersion ?? 138;
|
|
61
61
|
let currentVersion = readSchemaVersion(db);
|
|
62
62
|
if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
|
|
63
63
|
if (currentVersion >= targetVersion) return currentVersion;
|
|
@@ -94,7 +94,7 @@ function applyPendingMigrations(db, options = {}) {
|
|
|
94
94
|
}
|
|
95
95
|
/** Inspect schema version without mutating the database. */
|
|
96
96
|
function inspectSchemaMigrationStatus(db, options = {}) {
|
|
97
|
-
const appVersion = options.targetVersion ??
|
|
97
|
+
const appVersion = options.targetVersion ?? 138;
|
|
98
98
|
const dbVersion = readSchemaVersion(db);
|
|
99
99
|
if (dbVersion > appVersion) return {
|
|
100
100
|
dbVersion,
|
|
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
|
|
|
19
19
|
export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
20
20
|
|
|
21
21
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
22
|
-
export const XOPC_DB_SCHEMA_VERSION =
|
|
22
|
+
export const XOPC_DB_SCHEMA_VERSION = 138;
|
|
23
23
|
|
|
24
24
|
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
25
25
|
|
|
@@ -9,10 +9,10 @@ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
|
9
9
|
import { init_agent_scope, listAgentEntries, normalizeAgentId } from "../../agent/agent-scope.js";
|
|
10
10
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
11
11
|
import { effectiveWorkspacePathForSession } from "../../session/session-workspace.js";
|
|
12
|
-
import { createCreateShareTool, isShareToolAvailable } from "../../agent/tools/create-share-tool.js";
|
|
13
12
|
import { ProjectService } from "../../projects/project-service.js";
|
|
14
13
|
import { inferSuggestedProjectDefaultAgentId } from "../../projects/project-agent-suggestion.js";
|
|
15
14
|
import "../../projects/index.js";
|
|
15
|
+
import { createCreateShareTool, isShareToolAvailable } from "../../agent/tools/create-share-tool.js";
|
|
16
16
|
import { setTuiDefaultAgentConfig } from "../../commands/agents.config.js";
|
|
17
17
|
import { evictEmbeddedSessionRunner } from "../../agent/embedded/session-runner.js";
|
|
18
18
|
import { buildSessionTimeline } from "../../session/transcript-outline.js";
|