@xopcai/xopc 0.0.142 → 0.0.144
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 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
- package/dist/extensions/telegram/src/inbound-processor.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/activity-center-store-jITiX2vJ.js +1 -0
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BawPxiu5.js → agent-avatar-dicebear-EAVnrCAs.js} +1 -1
- package/dist/gateway/static/root/assets/agents-5rTuJOtT.js +2 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-81xd1p9R.js → app-management-settings-panel-Bu568NpC.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DYeQsYU8.js → appearance-settings-DSkm9bp_.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DWetalKp.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-D_oa7oti.js → archive-plugin-C99N0vV6.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-Cd-bwI2N.js → attachment-load-CHTDqME5.js} +1 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-CBt6U3-S.js +1 -0
- package/dist/gateway/static/root/assets/automations-page-ICUfxeOz.js +4 -0
- package/dist/gateway/static/root/assets/{binary-plugins-O8svLKWw.js → binary-plugins-BRtxOLlM.js} +1 -1
- package/dist/gateway/static/root/assets/block-editor-CUlXfgXd.js +184 -0
- package/dist/gateway/static/root/assets/browser-settings-page-D7Bj4MKi.js +8 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-dJy1Eqgx.js → capability-presets-api-Bg1ntFSD.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-C-8I-Ktn.js +2 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-Bfuhp2ty.js → channel-recipient-api-DuulnhIj.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-Dm5EqQyK.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-B5lVrUsN.js +1 -0
- package/dist/gateway/static/root/assets/check-BODqo66o.js +1 -0
- package/dist/gateway/static/root/assets/chunk-QUQL4437-DXsxWP7r.js +4 -0
- package/dist/gateway/static/root/assets/circle-alert-RzVebuX2.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-BOzjh-OK.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-DFMfIb5F.js → desktop-pet-C-Drhqyk.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-CRGiolqF.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BrYt1gAr.js → directory-picker-path-field-Dw1L3M84.js} +1 -1
- package/dist/gateway/static/root/assets/dist-SwiI0Xu3.js +1 -0
- package/dist/gateway/static/root/assets/dreaming-settings-CF21cbjo.js +3 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Bh630pLD.js → extension-debug-page-Dcl8LJG_.js} +1 -1
- package/dist/gateway/static/root/assets/extension-page-i_BXmO_x.js +1 -0
- package/dist/gateway/static/root/assets/extension-settings-page-CWIi7xsn.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-B1WtuprY.js → fetch-8QNN25Sh.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-De2N821l.js → gateway-config-api-2sLP2kkA.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-DMHiZc-2.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-nEujFSDj.js → gateway-startup-retry-5YBnS9Fj.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-CAODVDiA.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-_d4DjmeX.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-DUy3eEse.js → goals-config-api-B4qeLKQS.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-lgsop664.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-Dx_1ZNgb.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-DeTseEk_.js +1 -0
- package/dist/gateway/static/root/assets/index-CphxClbs.css +1 -0
- package/dist/gateway/static/root/assets/index-VWvztcst.js +257 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CVIwwM15.js → keyboard-shortcuts-settings-BpwpMmlk.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-9_hbTg3j.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-B_6us9j7.js → markdown-split-BTRFTK0w.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-D_fryIyj.js → media-plugins-BABfIZPU.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CzKxM6I4.js +5 -0
- package/dist/gateway/static/root/assets/models-hub-panel-B1CUvZxh.js +2 -0
- package/dist/gateway/static/root/assets/notes-page-88QBHW9a.js +1 -0
- package/dist/gateway/static/root/assets/notes-workbench-CerZOeLW.js +2 -0
- package/dist/gateway/static/root/assets/{page-tabs-D_8jGlqx.js → page-tabs-je95DZOf.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BBLMK8Mp.js → preview-open-alternatives-BJbwi7Rc.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BmrApldl.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-tTn-k76N.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-DeA2-pOi.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-DVS3FR5r.js → save-bar-controls-qWMQ9mod.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-D6vKd6-T.js → schedule-field-kxd270Gs.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-BPy4lbIh.js → schema-form-DLnD-MuD.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-D4kvvcL1.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CI1OG4gq.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-WzdikxPt.js → settings-collapsible-section-DQprvu5J.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-CvfzhBV-.js → settings-form-section-Cqq7Y98y.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-BxR-Ulhi.js → settings-loading-skeleton-b6rXULL5.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-BtBVz3cX.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-CKefvbYi.js → settings-page-layout-BNJbtklV.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-cmclUJzS.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page--zO-A1W1.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-DNJvqA67.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DWr_0Xgn.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-DEGsTbJx.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-BokgAgf7.js → system-settings-panel-Cq9J7i7v.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-BwHlNL3L.js → typed-models-lib-CdSwi1gT.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-DR11ap3A.js → use-channel-catalog-COXIfXcl.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-C-V73ZaJ.js +1 -0
- package/dist/gateway/static/root/assets/user-profile-fields-editor-B1cxoGkh.js +1 -0
- package/dist/gateway/static/root/assets/user-profile-settings-panel-B8hlamVB.js +1 -0
- package/dist/gateway/static/root/assets/{utils-BKUWB-TT.js → utils-Dx01V8qF.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-DGpIUelZ.js +1 -0
- package/dist/gateway/static/root/assets/with-selector-aYPsXwdl.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-fzWTxF26.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CL_rnAUB.js → workflow-run-setup-panel-Dt_x8LGg.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-Bg02zEUh.js +11 -0
- package/dist/gateway/static/root/assets/workflows-page-DLioOiRN.css +1 -0
- package/dist/gateway/static/root/connector-icons/README.md +11 -0
- package/dist/gateway/static/root/connector-icons/airtable.svg +13 -0
- package/dist/gateway/static/root/connector-icons/asana.svg +15 -0
- package/dist/gateway/static/root/connector-icons/brave-search.svg +1 -0
- package/dist/gateway/static/root/connector-icons/clickup.svg +19 -0
- package/dist/gateway/static/root/connector-icons/composio.svg +266 -0
- package/dist/gateway/static/root/connector-icons/discord.svg +15 -0
- package/dist/gateway/static/root/connector-icons/dropbox.svg +152 -0
- package/dist/gateway/static/root/connector-icons/excel.svg +56 -0
- package/dist/gateway/static/root/connector-icons/fetch.svg +6 -0
- package/dist/gateway/static/root/connector-icons/figma.svg +178 -0
- package/dist/gateway/static/root/connector-icons/filesystem.svg +6 -0
- package/dist/gateway/static/root/connector-icons/github.svg +10 -0
- package/dist/gateway/static/root/connector-icons/gmail.svg +3 -0
- package/dist/gateway/static/root/connector-icons/google-calendar.svg +3 -0
- package/dist/gateway/static/root/connector-icons/google-docs.svg +25 -0
- package/dist/gateway/static/root/connector-icons/google-drive.svg +25 -0
- package/dist/gateway/static/root/connector-icons/google-sheets.svg +1 -0
- package/dist/gateway/static/root/connector-icons/hubspot.svg +142 -0
- package/dist/gateway/static/root/connector-icons/jira.svg +15 -0
- package/dist/gateway/static/root/connector-icons/linear.svg +5 -0
- package/dist/gateway/static/root/connector-icons/memory.svg +5 -0
- package/dist/gateway/static/root/connector-icons/microsoft-teams.svg +33 -0
- package/dist/gateway/static/root/connector-icons/notion.svg +5 -0
- package/dist/gateway/static/root/connector-icons/one-drive.svg +13 -0
- package/dist/gateway/static/root/connector-icons/outlook.svg +76 -0
- package/dist/gateway/static/root/connector-icons/playwright.svg +9 -0
- package/dist/gateway/static/root/connector-icons/salesforce.svg +17 -0
- package/dist/gateway/static/root/connector-icons/sequential-thinking.svg +8 -0
- package/dist/gateway/static/root/connector-icons/shopify.svg +5 -0
- package/dist/gateway/static/root/connector-icons/slack.svg +9 -0
- package/dist/gateway/static/root/connector-icons/spotify.svg +43 -0
- package/dist/gateway/static/root/connector-icons/stripe.svg +11 -0
- package/dist/gateway/static/root/connector-icons/telegram.svg +130 -0
- package/dist/gateway/static/root/connector-icons/time.svg +6 -0
- package/dist/gateway/static/root/connector-icons/todoist.svg +277 -0
- package/dist/gateway/static/root/connector-icons/trello.svg +19 -0
- package/dist/gateway/static/root/connector-icons/twitter.svg +128 -0
- package/dist/gateway/static/root/connector-icons/whatsapp.svg +61 -0
- package/dist/gateway/static/root/connector-icons/youtube.svg +11 -0
- package/dist/gateway/static/root/index.html +10 -7
- package/dist/package.js +1 -1
- package/dist/src/activity/emitter.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +2 -0
- package/dist/src/agent/agent-manager.js +12 -4
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/background-review/prompts.d.ts +1 -1
- package/dist/src/agent/background-review/prompts.js +3 -2
- package/dist/src/agent/background-review/prompts.js.map +1 -1
- package/dist/src/agent/code-intelligence/binary.js +1 -1
- package/dist/src/agent/context/project-context.js +2 -2
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +1 -1
- package/dist/src/agent/embedded/xopc-tools-bridge.d.ts +9 -0
- package/dist/src/agent/embedded/xopc-tools-bridge.js +71 -3
- package/dist/src/agent/embedded/xopc-tools-bridge.js.map +1 -1
- package/dist/src/agent/goals/post-turn.js +7 -6
- package/dist/src/agent/goals/post-turn.js.map +1 -1
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +5 -2
- package/dist/src/agent/mcp/mcp-transport.js.map +1 -1
- package/dist/src/agent/memory/context/planner.d.ts +1 -0
- package/dist/src/agent/memory/context/planner.js +60 -14
- package/dist/src/agent/memory/context/planner.js.map +1 -1
- package/dist/src/agent/memory/context/types.d.ts +3 -1
- package/dist/src/agent/memory/lifecycle.d.ts +11 -0
- package/dist/src/agent/memory/lifecycle.js +50 -0
- package/dist/src/agent/memory/lifecycle.js.map +1 -0
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/memory/source-origin.d.ts +3 -0
- package/dist/src/agent/memory/source-origin.js +19 -0
- package/dist/src/agent/memory/source-origin.js.map +1 -0
- package/dist/src/agent/memory/understanding/service.js +5 -0
- package/dist/src/agent/memory/understanding/service.js.map +1 -1
- package/dist/src/agent/memory/user-context-coordinator.js +7 -2
- package/dist/src/agent/memory/user-context-coordinator.js.map +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
- package/dist/src/agent/prompt/sections/behavior.d.ts +2 -0
- package/dist/src/agent/prompt/sections/behavior.js +30 -1
- package/dist/src/agent/prompt/sections/behavior.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +1 -1
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +8 -1
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/prompt/system-prompt.d.ts +2 -0
- package/dist/src/agent/prompt/system-prompt.js +6 -3
- package/dist/src/agent/prompt/system-prompt.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +22 -0
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service.d.ts +2 -0
- package/dist/src/agent/service.js +12 -6
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +2 -2
- package/dist/src/agent/skills/hub-pull.js +1 -1
- package/dist/src/agent/starter-agents.js +1 -1
- package/dist/src/agent/starter-agents.js.map +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js.map +1 -1
- package/dist/src/agent/tools/composio-tool.d.ts +18 -5
- package/dist/src/agent/tools/composio-tool.js +252 -35
- package/dist/src/agent/tools/composio-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.js +7 -3
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/goal-tool.js +2 -2
- package/dist/src/agent/tools/index.d.ts +1 -1
- package/dist/src/agent/tools/index.js +2 -2
- package/dist/src/agent/tools/workflow-tool.d.ts +0 -1
- package/dist/src/agent/tools/workflow-tool.js +4 -17
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/tools/xopc-use-tool.js +1 -1
- package/dist/src/agent/workflow/builtins/index.d.ts +2 -28
- package/dist/src/agent/workflow/builtins/index.js +226 -41
- package/dist/src/agent/workflow/builtins/index.js.map +1 -1
- package/dist/src/agent/workflow/catalog.d.ts +32 -34
- package/dist/src/agent/workflow/catalog.js +158 -154
- package/dist/src/agent/workflow/catalog.js.map +1 -1
- package/dist/src/agent/workflow/index.d.ts +4 -6
- package/dist/src/agent/workflow/index.js +2 -5
- package/dist/src/agent/workflow/snapshot.d.ts +2 -2
- package/dist/src/agent/workflow/snapshot.js +2 -2
- package/dist/src/agent/workflow/snapshot.js.map +1 -1
- package/dist/src/agent/workflow/structured-output-tool.d.ts +2 -2
- package/dist/src/agent/workflow/structured-output-tool.js +2 -2
- package/dist/src/agent/workflow/structured-output-tool.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.js +1 -1
- package/dist/src/agent/workflow/types.d.ts +31 -26
- package/dist/src/agent/workspace-runtime/registry.js +2 -2
- package/dist/src/agent-manifest/index.d.ts +1 -0
- package/dist/src/agent-manifest/index.js +3 -1
- package/dist/src/agent-manifest/index.js.map +1 -1
- package/dist/src/agent-manifest/preset-chain.d.ts +10 -0
- package/dist/src/agent-manifest/preset-chain.js +32 -0
- package/dist/src/agent-manifest/preset-chain.js.map +1 -0
- package/dist/src/agent-manifest/resolver.js +3 -10
- package/dist/src/agent-manifest/resolver.js.map +1 -1
- package/dist/src/agent-manifest/schema.d.ts +4 -4
- package/dist/src/automations/api/routes.js +14 -2
- package/dist/src/automations/api/routes.js.map +1 -1
- package/dist/src/automations/domain/validation.d.ts +14 -14
- package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -3
- package/dist/src/automations/service/action-executor.js +2 -2
- package/dist/src/browser/cdp-local-launcher.js +1 -1
- package/dist/src/browser/providers/browser-ext-install.d.ts +11 -1
- package/dist/src/browser/providers/browser-ext-install.js +42 -17
- package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +2 -2
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/capabilities/store-connector.d.ts +0 -1
- package/dist/src/capabilities/store-connector.js +4 -6
- package/dist/src/capabilities/store-connector.js.map +1 -1
- package/dist/src/chat-commands/agent-edit.js +1 -1
- package/dist/src/chat-commands/builtins/config.js +1 -1
- package/dist/src/chat-commands/builtins/goal.js +2 -2
- package/dist/src/chat-commands/builtins/review.js +72 -73
- package/dist/src/chat-commands/builtins/review.js.map +1 -1
- package/dist/src/chat-commands/builtins/workflow.js +9 -54
- package/dist/src/chat-commands/builtins/workflow.js.map +1 -1
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/commands/agent.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +2 -2
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/extension-create.js +2 -2
- package/dist/src/cli/commands/extension-create.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +43 -37
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.d.ts +6 -0
- package/dist/src/cli/commands/extension-pack.js +4 -3
- package/dist/src/cli/commands/extension-pack.js.map +1 -1
- package/dist/src/cli/commands/goal.js +2 -2
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/project.js +3 -3
- package/dist/src/commands/agents.config.d.ts +1 -0
- package/dist/src/commands/agents.config.js +1 -0
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +1 -1
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.d.ts +6 -6
- package/dist/src/config/schema.js +6 -22
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/web-patch.d.ts +1 -1
- package/dist/src/connectors/approval.d.ts +2 -0
- package/dist/src/connectors/approval.js +33 -0
- package/dist/src/connectors/approval.js.map +1 -0
- package/dist/src/connectors/auth-provider-registry.d.ts +9 -0
- package/dist/src/connectors/auth-provider-registry.js +17 -0
- package/dist/src/connectors/auth-provider-registry.js.map +1 -0
- package/dist/src/connectors/builtin-catalog.js +55 -116
- package/dist/src/connectors/builtin-catalog.js.map +1 -1
- package/dist/src/connectors/catalog.js +7 -2
- package/dist/src/connectors/catalog.js.map +1 -1
- package/dist/src/connectors/composio-catalog.d.ts +19 -0
- package/dist/src/connectors/composio-catalog.js +237 -0
- package/dist/src/connectors/composio-catalog.js.map +1 -0
- package/dist/src/connectors/composio-logo.d.ts +1 -0
- package/dist/src/connectors/composio-logo.js +51 -0
- package/dist/src/connectors/composio-logo.js.map +1 -0
- package/dist/src/connectors/composio-sessions.d.ts +116 -0
- package/dist/src/connectors/composio-sessions.js +296 -0
- package/dist/src/connectors/composio-sessions.js.map +1 -0
- package/dist/src/connectors/composio-triggers.d.ts +17 -0
- package/dist/src/connectors/composio-triggers.js +48 -5
- package/dist/src/connectors/composio-triggers.js.map +1 -1
- package/dist/src/connectors/composio.d.ts +31 -2
- package/dist/src/connectors/composio.js +374 -151
- package/dist/src/connectors/composio.js.map +1 -1
- package/dist/src/connectors/connector-memory-sync.d.ts +15 -0
- package/dist/src/connectors/connector-memory-sync.js +90 -0
- package/dist/src/connectors/connector-memory-sync.js.map +1 -0
- package/dist/src/connectors/install.js +35 -92
- package/dist/src/connectors/install.js.map +1 -1
- package/dist/src/connectors/instances.js +6 -2
- package/dist/src/connectors/instances.js.map +1 -1
- package/dist/src/connectors/integration-strategy.d.ts +3 -0
- package/dist/src/connectors/integration-strategy.js +29 -0
- package/dist/src/connectors/integration-strategy.js.map +1 -0
- package/dist/src/connectors/policy.d.ts +13 -0
- package/dist/src/connectors/policy.js +48 -0
- package/dist/src/connectors/policy.js.map +1 -0
- package/dist/src/connectors/providers.js +1 -1
- package/dist/src/connectors/runtime-adapter-registry.d.ts +25 -0
- package/dist/src/connectors/runtime-adapter-registry.js +154 -0
- package/dist/src/connectors/runtime-adapter-registry.js.map +1 -0
- package/dist/src/connectors/types.d.ts +113 -4
- package/dist/src/connectors/workflow-preflight.d.ts +20 -0
- package/dist/src/connectors/workflow-preflight.js +70 -0
- package/dist/src/connectors/workflow-preflight.js.map +1 -0
- package/dist/src/daemon/launchd.js +1 -1
- package/dist/src/daemon/systemd.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/install-transaction.d.ts +16 -0
- package/dist/src/extensions/install-transaction.js +76 -0
- package/dist/src/extensions/install-transaction.js.map +1 -0
- package/dist/src/extensions/install.d.ts +2 -0
- package/dist/src/extensions/install.js +23 -1
- package/dist/src/extensions/install.js.map +1 -1
- package/dist/src/extensions/loader.js +2 -2
- package/dist/src/gateway/agents-admin.d.ts +2 -0
- package/dist/src/gateway/agents-admin.js +7 -0
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/capability-presets-admin.d.ts +11 -0
- package/dist/src/gateway/capability-presets-admin.js +11 -4
- package/dist/src/gateway/capability-presets-admin.js.map +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +17 -0
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +18 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -3
- package/dist/src/gateway/hono/lib/static-ui.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +3 -0
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/capability-presets.js +19 -1
- package/dist/src/gateway/hono/routes/capability-presets.js.map +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +188 -25
- package/dist/src/gateway/hono/routes/connectors.js.map +1 -1
- package/dist/src/gateway/hono/routes/goals.js +22 -3
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +60 -1
- package/dist/src/gateway/hono/routes/home.js +244 -18
- package/dist/src/gateway/hono/routes/home.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/memory.js +17 -4
- package/dist/src/gateway/hono/routes/memory.js.map +1 -1
- package/dist/src/gateway/hono/routes/projects.js +106 -5
- package/dist/src/gateway/hono/routes/projects.js.map +1 -1
- package/dist/src/gateway/hono/routes/public-gateway.js +93 -0
- package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +137 -22
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/routes/you.d.ts +23 -0
- package/dist/src/gateway/hono/routes/you.js +538 -0
- package/dist/src/gateway/hono/routes/you.js.map +1 -0
- package/dist/src/gateway/hono/sse.d.ts +2 -1
- package/dist/src/gateway/hono/sse.js +2 -1
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/lock.js +1 -1
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +13 -1
- package/dist/src/gateway/service/marketplace-service.js +96 -40
- package/dist/src/gateway/service/marketplace-service.js.map +1 -1
- package/dist/src/gateway/service.d.ts +2 -0
- package/dist/src/gateway/service.js +13 -7
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/goals/goal-service.d.ts +7 -5
- package/dist/src/goals/goal-service.js +25 -13
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/goals/goal-store.js +46 -7
- package/dist/src/goals/goal-store.js.map +1 -1
- package/dist/src/goals/goal-workflow-judge.js +1 -1
- package/dist/src/goals/types.d.ts +24 -0
- package/dist/src/infra/ports.js +1 -1
- package/dist/src/infra/ssh-tunnel.js +1 -1
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/migrations/runner.js +1 -1
- package/dist/src/notes/service.js +3 -3
- package/dist/src/notes/store.js +1 -1
- package/dist/src/projects/project-service.js +1 -1
- package/dist/src/projects/workspace.js +1 -1
- package/dist/src/routing/agent-session-key.js +1 -1
- package/dist/src/routing/resolve-route.js +1 -1
- package/dist/src/routing/resolve-tui-session-key.js +1 -1
- package/dist/src/session/init-session-turn.js +1 -1
- package/dist/src/session/resolve-session.js +1 -1
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.js +1 -1
- package/dist/src/storage/sqlite/connection.js +1 -1
- package/dist/src/storage/sqlite/connector-repository.d.ts +49 -0
- package/dist/src/storage/sqlite/connector-repository.js +385 -0
- package/dist/src/storage/sqlite/connector-repository.js.map +1 -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/030_connectors.sql +94 -0
- package/dist/src/storage/sqlite/migrations/031_connector_approvals.sql +24 -0
- package/dist/src/storage/sqlite/migrations/032_connector_webhook_deliveries.sql +15 -0
- package/dist/src/storage/sqlite/migrations/033_user_trust_policies.sql +6 -0
- package/dist/src/storage/sqlite/migrations/034_allow_global_auto_trust.sql +14 -0
- package/dist/src/storage/sqlite/migrations/035_user_profile_prompt_state.sql +7 -0
- package/dist/src/storage/sqlite/migrations/036_goal_outcome_metric.sql +12 -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.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/row-mappers.js +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/user-profile-setup-repository.d.ts +3 -0
- package/dist/src/storage/sqlite/user-profile-setup-repository.js +34 -0
- package/dist/src/storage/sqlite/user-profile-setup-repository.js.map +1 -0
- package/dist/src/storage/sqlite/user-trust-repository.d.ts +3 -0
- package/dist/src/storage/sqlite/user-trust-repository.js +34 -0
- package/dist/src/storage/sqlite/user-trust-repository.js.map +1 -0
- package/dist/src/tui/backends/embedded-backend.js +4 -4
- package/dist/src/tui/clipboard-image.js +1 -1
- package/dist/src/tui/components/assistant-message.js +15 -0
- package/dist/src/tui/components/assistant-message.js.map +1 -1
- package/dist/src/tui/tui-agent-events.js +85 -1
- package/dist/src/tui/tui-agent-events.js.map +1 -1
- package/dist/src/tui/tui-command-formatters.js +9 -9
- package/dist/src/tui/tui-command-formatters.js.map +1 -1
- package/dist/src/tui/tui-commands.js +4 -4
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/user-context/import.d.ts +12 -0
- package/dist/src/user-context/import.js +48 -0
- package/dist/src/user-context/import.js.map +1 -0
- package/dist/src/user-context/profile.d.ts +37 -0
- package/dist/src/user-context/profile.js +165 -0
- package/dist/src/user-context/profile.js.map +1 -0
- package/dist/src/user-context/projection.d.ts +54 -0
- package/dist/src/user-context/projection.js +121 -0
- package/dist/src/user-context/projection.js.map +1 -0
- package/dist/src/user-context/source-recommendations.d.ts +13 -0
- package/dist/src/user-context/source-recommendations.js +86 -0
- package/dist/src/user-context/source-recommendations.js.map +1 -0
- package/dist/src/user-context/trust-policy.d.ts +11 -0
- package/dist/src/user-context/trust-policy.js +31 -0
- package/dist/src/user-context/trust-policy.js.map +1 -0
- package/dist/src/utils/index.js +1 -1
- package/dist/src/utils/logger/index.js +1 -1
- package/dist/src/utils/logger.js +1 -1
- package/dist/src/work-items/work-item-service.js +1 -1
- package/dist/src/workflows/authoring/index.d.ts +1 -0
- package/dist/src/workflows/authoring/index.js +2 -0
- package/dist/src/workflows/authoring/workflow-draft-store.d.ts +33 -0
- package/dist/src/workflows/authoring/workflow-draft-store.js +74 -0
- package/dist/src/workflows/authoring/workflow-draft-store.js.map +1 -0
- package/dist/src/workflows/domain/definition-utils.d.ts +6 -4
- package/dist/src/workflows/domain/definition-utils.js +28 -26
- package/dist/src/workflows/domain/definition-utils.js.map +1 -1
- package/dist/src/workflows/domain/definition.d.ts +79 -6
- package/dist/src/workflows/domain/event.d.ts +18 -2
- package/dist/src/workflows/domain/index.js +3 -3
- package/dist/src/workflows/domain/run.d.ts +16 -2
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/domain/validation.d.ts +9 -5
- package/dist/src/workflows/domain/validation.js +183 -40
- package/dist/src/workflows/domain/validation.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft-prompt.d.ts +2 -3
- package/dist/src/workflows/draft/workflow-draft-prompt.js +31 -73
- package/dist/src/workflows/draft/workflow-draft-prompt.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft-service.js +5 -9
- package/dist/src/workflows/draft/workflow-draft-service.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft-validator.js +29 -37
- package/dist/src/workflows/draft/workflow-draft-validator.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft.types.d.ts +4 -4
- package/dist/src/workflows/engine/projector.js +43 -1
- package/dist/src/workflows/engine/projector.js.map +1 -1
- package/dist/src/workflows/engine/workflow-engine.d.ts +2 -3
- package/dist/src/workflows/engine/workflow-engine.js +24 -4
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.js +4 -7
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.js +1 -9
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.js.map +1 -1
- package/dist/src/workflows/runtime/graph-workflow-runtime.d.ts +10 -0
- package/dist/src/workflows/runtime/graph-workflow-runtime.js +295 -0
- package/dist/src/workflows/runtime/graph-workflow-runtime.js.map +1 -0
- package/dist/src/workflows/runtime/index.d.ts +1 -2
- package/dist/src/workflows/runtime/index.js +2 -5
- package/dist/src/workflows/runtime/workflow-runtime-port.d.ts +5 -8
- package/dist/src/workflows/service/workflow-run-service.js +15 -1
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +2 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +3 -3
- package/package.json +5 -4
- package/dist/gateway/static/root/assets/agents-CyvCIHnB.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-DK_Vx6nl.js +0 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-B1LV3YYv.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-fzrovqhv.js +0 -4
- package/dist/gateway/static/root/assets/block-editor-Dhj5f4Bx.js +0 -184
- package/dist/gateway/static/root/assets/browser-settings-page-BDn-n-UB.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Co5ipo_Q.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BWlpaxg9.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-D_jkIZLV.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BcekbW4q.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-settings-BJCUuL8Y.js +0 -1
- package/dist/gateway/static/root/assets/dist-Mys7eFJ5.js +0 -1
- package/dist/gateway/static/root/assets/dreaming-settings-BN1Z2mIo.js +0 -3
- package/dist/gateway/static/root/assets/extension-page-B-1KxvVy.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BF9NACI3.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-DN9sNREz.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-BpoQW8cD.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-CBRSPd0b.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-BCcBi407.js +0 -2
- package/dist/gateway/static/root/assets/goals-settings-pkTXzXkh.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-ezsufgLQ.js +0 -1
- package/dist/gateway/static/root/assets/index-B8s8Pq5U.css +0 -1
- package/dist/gateway/static/root/assets/index-DcUaXYeb.js +0 -262
- package/dist/gateway/static/root/assets/logs-page-DQtTRXtj.js +0 -7
- package/dist/gateway/static/root/assets/messages-BXNELNBa.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-BP2M9n6Q.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-CspveYaO.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-BHwzJ0OC.js +0 -2
- package/dist/gateway/static/root/assets/project-detail-page-Dy3rsobs.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CWKpPE0L.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CqNRyXEo.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-MEME7ivF.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-JVd0qaSF.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-DYEbB1EV.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-dWN8BJ3z.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-D8foINzP.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-Tgbv1s7G.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-D_YK0b_Z.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-DGytfoZK.js +0 -2
- package/dist/gateway/static/root/assets/toast-z0toXu32.js +0 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-8YtygcJp.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-BVH71EFf.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-JeTE7XNM.js +0 -1
- package/dist/gateway/static/root/assets/workflow-start-dialog-_u8Uc1ze.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-ixgk_y1l.js +0 -18
- package/dist/src/agent/workflow/builtins/audit-repo.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/audit-repo.js +0 -183
- package/dist/src/agent/workflow/builtins/audit-repo.js.map +0 -1
- package/dist/src/agent/workflow/builtins/client-proposal.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/client-proposal.js +0 -164
- package/dist/src/agent/workflow/builtins/client-proposal.js.map +0 -1
- package/dist/src/agent/workflow/builtins/competitor-scan.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/competitor-scan.js +0 -164
- package/dist/src/agent/workflow/builtins/competitor-scan.js.map +0 -1
- package/dist/src/agent/workflow/builtins/content-draft.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/content-draft.js +0 -159
- package/dist/src/agent/workflow/builtins/content-draft.js.map +0 -1
- package/dist/src/agent/workflow/builtins/content-repurpose.d.ts +0 -11
- package/dist/src/agent/workflow/builtins/content-repurpose.js +0 -146
- package/dist/src/agent/workflow/builtins/content-repurpose.js.map +0 -1
- package/dist/src/agent/workflow/builtins/debug-incident.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/debug-incident.js +0 -177
- package/dist/src/agent/workflow/builtins/debug-incident.js.map +0 -1
- package/dist/src/agent/workflow/builtins/decision-compare.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/decision-compare.js +0 -187
- package/dist/src/agent/workflow/builtins/decision-compare.js.map +0 -1
- package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/implementation-plan.js +0 -185
- package/dist/src/agent/workflow/builtins/implementation-plan.js.map +0 -1
- package/dist/src/agent/workflow/builtins/inbox-triage.d.ts +0 -11
- package/dist/src/agent/workflow/builtins/inbox-triage.js +0 -158
- package/dist/src/agent/workflow/builtins/inbox-triage.js.map +0 -1
- package/dist/src/agent/workflow/builtins/meeting-prep.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/meeting-prep.js +0 -152
- package/dist/src/agent/workflow/builtins/meeting-prep.js.map +0 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +0 -14
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js +0 -171
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +0 -1
- package/dist/src/agent/workflow/builtins/offer-design.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/offer-design.js +0 -170
- package/dist/src/agent/workflow/builtins/offer-design.js.map +0 -1
- package/dist/src/agent/workflow/builtins/pr-review.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/pr-review.js +0 -178
- package/dist/src/agent/workflow/builtins/pr-review.js.map +0 -1
- package/dist/src/agent/workflow/builtins/release-check.d.ts +0 -11
- package/dist/src/agent/workflow/builtins/release-check.js +0 -174
- package/dist/src/agent/workflow/builtins/release-check.js.map +0 -1
- package/dist/src/agent/workflow/builtins/research.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/research.js +0 -188
- package/dist/src/agent/workflow/builtins/research.js.map +0 -1
- package/dist/src/agent/workflow/builtins/weekly-review.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/weekly-review.js +0 -139
- package/dist/src/agent/workflow/builtins/weekly-review.js.map +0 -1
- package/dist/src/agent/workflow/last-run-memory.d.ts +0 -42
- package/dist/src/agent/workflow/last-run-memory.js +0 -60
- package/dist/src/agent/workflow/last-run-memory.js.map +0 -1
- package/dist/src/agent/workflow/lint.d.ts +0 -38
- package/dist/src/agent/workflow/lint.js +0 -74
- package/dist/src/agent/workflow/lint.js.map +0 -1
- package/dist/src/agent/workflow/meta-locale.d.ts +0 -12
- package/dist/src/agent/workflow/meta-locale.js +0 -62
- package/dist/src/agent/workflow/meta-locale.js.map +0 -1
- package/dist/src/agent/workflow/parser.d.ts +0 -20
- package/dist/src/agent/workflow/parser.js +0 -152
- package/dist/src/agent/workflow/parser.js.map +0 -1
- package/dist/src/agent/workflow/runtime.d.ts +0 -34
- package/dist/src/agent/workflow/runtime.js +0 -402
- package/dist/src/agent/workflow/runtime.js.map +0 -1
- package/dist/src/connectors/oauth.d.ts +0 -22
- package/dist/src/connectors/oauth.js +0 -99
- package/dist/src/connectors/oauth.js.map +0 -1
- package/dist/src/workflows/runtime/script-runtime.d.ts +0 -3
- package/dist/src/workflows/runtime/script-runtime.js +0 -3
- package/dist/src/workflows/runtime/script-workflow-runtime.d.ts +0 -5
- package/dist/src/workflows/runtime/script-workflow-runtime.js +0 -15
- package/dist/src/workflows/runtime/script-workflow-runtime.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.js","names":[],"sources":["../../../../src/gateway/hono/sse.ts"],"sourcesContent":["import { streamSSE } from 'hono/streaming';\nimport type { Context } from 'hono';\nimport type { GatewayService } from '../service.js';\nimport { MAX_WEBCHAT_ATTACHMENT_FILE_BYTES } from '../chat-limits.js';\nimport { createLogger, updateAsyncLogContext } from '../../utils/logger.js';\nimport { stringifySSEData } from './sse-json.js';\nimport { resolveWebchatSessionKey } from '../resolve-webchat-session-key.js';\nimport type { UserTurnAttachment } from '../user-turn-input.js';\n\nconst log = createLogger('Gateway:SSE');\n\n// Active SSE connections tracking for connection limiting\nconst activeConnections = new Map<string, AbortController>();\n\nexport interface SSEHandlerConfig {\n service: GatewayService;\n maxSseConnections?: number;\n}\n\n// Type validation for agent request body\ninterface AgentRequestBody {\n message: string;\n channel?: string;\n sessionKey?: string;\n /** Epoch ms when the client started this send (abort cutoff / stale POST drop). */\n clientCreatedAtMs?: number;\n thinking?: string;\n attachments?: UserTurnAttachment[];\n}\n\nfunction isValidAgentRequest(body: unknown): body is AgentRequestBody {\n if (!body || typeof body !== 'object') return false;\n const b = body as Record<string, unknown>;\n // Allow empty message if attachments are provided\n const hasMessage = typeof b.message === 'string';\n const hasAttachments = Array.isArray(b.attachments) && b.attachments.length > 0;\n return hasMessage || hasAttachments;\n}\n\n/** Max base64 character length that can decode to `MAX_WEBCHAT_ATTACHMENT_FILE_BYTES`. */\nfunction maxBase64CharsForBinary(maxBinaryBytes: number): number {\n return 4 * Math.ceil(maxBinaryBytes / 3);\n}\n\n/**\n * POST /api/agent — Send a message to the agent, stream response via SSE.\n *\n * Request body: { message, channel?, sessionKey, attachments? }\n * Accept: text/event-stream → SSE stream\n * Accept: application/json → wait for full response, return JSON\n *\n * SSE events follow XOPC Chat Stream Protocol v1:\n * run_start, user_message, user_transcript, assistant_message_start,\n * assistant_delta, thinking_delta, thinking_end, tool_start, tool_update,\n * tool_end, assistant_message_end, compaction, tts_audio, clarify_request,\n * run_end, error.\n */\nexport function createAgentSSEHandler(config: SSEHandlerConfig) {\n const { service } = config;\n\n return async (c: Context) => {\n const body = await c.req.json().catch(() => null);\n\n // Input validation\n if (!isValidAgentRequest(body)) {\n return c.json({\n ok: false,\n error: { code: 'BAD_REQUEST', message: 'Missing required field: message or attachments' }\n }, 400);\n }\n\n const { message, channel = 'webchat', attachments, thinking } = body;\n const clientCreatedAtMs =\n typeof body.clientCreatedAtMs === 'number' && Number.isFinite(body.clientCreatedAtMs)\n ? body.clientCreatedAtMs\n : undefined;\n const resolved = resolveWebchatSessionKey({\n sessionKey: typeof body.sessionKey === 'string' ? body.sessionKey : undefined,\n });\n if (resolved.ok === false) {\n return c.json({\n ok: false,\n error: { code: 'BAD_REQUEST', message: resolved.error },\n }, 400);\n }\n const chatId = resolved.sessionKey;\n\n updateAsyncLogContext({ sessionKey: String(chatId) });\n\n if (Array.isArray(attachments)) {\n const maxDataChars = maxBase64CharsForBinary(MAX_WEBCHAT_ATTACHMENT_FILE_BYTES);\n for (const a of attachments) {\n if (!a || typeof a !== 'object') continue;\n const data = (a as { data?: unknown }).data;\n if (typeof data === 'string' && data.length > maxDataChars) {\n return c.json(\n {\n ok: false,\n error: {\n code: 'BAD_REQUEST',\n message: `Attachment exceeds maximum size (${MAX_WEBCHAT_ATTACHMENT_FILE_BYTES} bytes)`,\n },\n },\n 400,\n );\n }\n }\n }\n\n const accept = c.req.header('Accept') || '';\n const wantSSE = accept.includes('text/event-stream');\n\n const clientAbort = new AbortController();\n const raw = c.req.raw;\n // Keep webchat runs alive across transient disconnects (page refresh / tab route switch)\n // so the client can reattach via /api/agent/resume using runId from `run_start`.\n // Explicit cancellation still goes through /api/agent/abort.\n if (channel !== 'webchat') {\n if (raw.signal.aborted) {\n clientAbort.abort();\n } else {\n raw.signal.addEventListener('abort', () => clientAbort.abort(), { once: true });\n }\n }\n\n // --- Non-streaming fallback: collect everything, return JSON ---\n if (!wantSSE) {\n const jsonSessionKey = channel === 'webchat' ? chatId : undefined;\n\n const generator = service.runAgent(message, channel, chatId, attachments, thinking, {\n signal: clientAbort.signal,\n ...(clientCreatedAtMs !== undefined ? { clientCreatedAtMs } : {}),\n });\n try {\n let finalResult: { status: string; summary: string } | undefined;\n const tokens: string[] = [];\n\n while (true) {\n const { done, value } = await generator.next();\n if (done) {\n finalResult = value as { status: string; summary: string };\n break;\n }\n const chunk = value as { type: string; payload?: { delta?: unknown } };\n if (chunk.type === 'assistant_delta' && typeof chunk.payload?.delta === 'string') {\n tokens.push(chunk.payload.delta);\n }\n }\n\n return c.json({\n ok: true,\n payload: {\n ...finalResult,\n content: tokens.join(''),\n ...(jsonSessionKey !== undefined\n ? { sessionKey: jsonSessionKey, key: jsonSessionKey }\n : {}),\n },\n });\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.error(\n { err: error, errorMessage: em, phase: 'gateway.agent_run', sessionKey: jsonSessionKey, channel },\n `Agent run failed (JSON mode): ${em}`,\n );\n return c.json({\n ok: false,\n error: { code: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : 'Unknown error' },\n }, 500);\n }\n }\n\n // --- SSE streaming ---\n c.header('X-Accel-Buffering', 'no');\n return streamSSE(c, async (stream) => {\n if (channel !== 'webchat') {\n stream.onAbort(() => {\n clientAbort.abort();\n });\n }\n\n const generator = service.runAgent(message, channel, chatId, attachments, thinking, {\n signal: clientAbort.signal,\n ...(clientCreatedAtMs !== undefined ? { clientCreatedAtMs } : {}),\n });\n\n let eventId = 0;\n\n try {\n while (true) {\n const { done, value } = await generator.next();\n\n if (done) break;\n\n const chunk = value as { type: string; seq?: unknown };\n await stream.writeSSE({\n id: typeof chunk.seq === 'number' ? String(chunk.seq) : String(++eventId),\n event: chunk.type || 'message',\n data: stringifySSEData(chunk),\n });\n }\n } catch (error) {\n log.error({ err: error }, 'Agent run failed (SSE mode)');\n await stream.writeSSE({\n id: String(++eventId),\n event: 'error',\n data: stringifySSEData({\n type: 'error',\n runId: 'unknown',\n sessionKey: chatId,\n timestamp: Date.now(),\n payload: { code: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : 'Unknown error' },\n }),\n });\n }\n });\n };\n}\n\n/**\n * POST /api/agent/resume — Re-attach to an in-progress agent run via SSE.\n *\n * Request body: { runId, sessionKey }\n * The relay replays all buffered events from the beginning and then live-tails\n * until the run completes.\n *\n * SSE events are identical to those from POST /api/agent.\n */\nexport function createAgentResumeHandler(config: SSEHandlerConfig) {\n const { service } = config;\n\n return async (c: Context) => {\n const body = await c.req.json().catch(() => null);\n if (!body || typeof body !== 'object') {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Invalid JSON body' } }, 400);\n }\n\n const { runId, sessionKey } = body as { runId?: string; sessionKey?: string };\n if (typeof sessionKey === 'string' && sessionKey.trim()) {\n updateAsyncLogContext({ sessionKey: sessionKey.trim() });\n }\n if (!runId || typeof runId !== 'string') {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Missing required field: runId' } }, 400);\n }\n\n if (!service.runRelay.hasRun(runId)) {\n return c.json({ ok: false, error: { code: 'NOT_FOUND', message: 'Run not found or already expired' } }, 404);\n }\n\n c.header('X-Accel-Buffering', 'no');\n return streamSSE(c, async (stream) => {\n let eventId = 0;\n try {\n for await (const event of service.runRelay.subscribe(runId)) {\n await stream.writeSSE({\n id: typeof event.seq === 'number' ? String(event.seq) : String(++eventId),\n event: event.type || 'message',\n data: stringifySSEData(event),\n });\n }\n } catch (error) {\n log.error({ err: error, runId }, 'Resume stream failed');\n await stream.writeSSE({\n id: String(++eventId),\n event: 'error',\n data: stringifySSEData({\n type: 'error',\n runId,\n sessionKey: typeof sessionKey === 'string' ? sessionKey : '',\n timestamp: Date.now(),\n payload: { code: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : 'Unknown error' },\n }),\n });\n }\n });\n };\n}\n\n/**\n * POST /api/send — Send a message through a channel (non-streaming).\n */\nexport function createSendHandler(config: SSEHandlerConfig) {\n const { service } = config;\n\n return async (c: Context) => {\n const body = await c.req.json().catch(() => ({}));\n const channel = body.channel as string;\n const chatId = body.chatId as string;\n const content = body.content as string;\n\n if (!channel || !chatId || !content) {\n return c.json(\n { ok: false, error: { code: 'BAD_REQUEST', message: 'Missing required fields: channel, chatId, content' } },\n 400,\n );\n }\n\n try {\n const result = await service.sendMessage(channel, chatId, content);\n return c.json({ ok: true, payload: result });\n } catch (error) {\n log.error({ err: error }, 'Send failed');\n return c.json(\n { ok: false, error: { code: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : 'Unknown error' } },\n 500,\n );\n }\n };\n}\n\n/**\n * GET /api/events — Server-pushed event stream (SSE).\n *\n * The client opens this long-lived connection to receive:\n * - channel status changes\n * - config reload notifications\n * - cron execution results\n * - any other server-initiated events\n *\n * Supports Last-Event-ID for reconnection.\n * Enforces maximum connection limit to prevent DoS.\n */\nexport function createEventsSSEHandler(config: SSEHandlerConfig) {\n const { service } = config;\n const maxConnections = config.maxSseConnections ?? 100;\n\n return async (c: Context) => {\n // Check maximum connections limit\n if (activeConnections.size >= maxConnections) {\n log.warn({ current: activeConnections.size, max: maxConnections }, 'SSE connection limit reached');\n return c.json({\n ok: false,\n error: { code: 'TOO_MANY_CONNECTIONS', message: 'Maximum SSE connections exceeded' }\n }, 503);\n }\n\n const lastEventId = c.req.header('Last-Event-ID') || undefined;\n const sessionId = c.req.header('X-Session-Id')\n || c.req.query('sessionId')\n || crypto.randomUUID();\n\n updateAsyncLogContext({ sessionId: String(sessionId) });\n\n const abortController = new AbortController();\n activeConnections.set(sessionId, abortController);\n\n return streamSSE(c, async (stream) => {\n let aborted = false;\n\n // Send a hello event so the client knows the stream is established\n await stream.writeSSE({\n id: '0',\n event: 'connected',\n data: JSON.stringify({ sessionId }),\n });\n\n // Subscribe to service events\n const cleanup = service.subscribe(sessionId, async (event) => {\n if (aborted) return;\n try {\n await stream.writeSSE({\n id: event.id,\n event: event.type,\n data: JSON.stringify(event.payload),\n });\n } catch {\n // Stream closed, will be cleaned up by onAbort\n }\n });\n\n // Replay missed events on reconnect\n if (lastEventId) {\n const missed = service.getEventsSince(sessionId, lastEventId);\n for (const event of missed) {\n await stream.writeSSE({\n id: event.id,\n event: event.type,\n data: JSON.stringify(event.payload),\n });\n }\n }\n\n // Keep alive with periodic comments (every 30s)\n const keepAlive = setInterval(async () => {\n if (aborted) { clearInterval(keepAlive); return; }\n try {\n await stream.writeSSE({ event: 'ping', data: '' });\n } catch {\n clearInterval(keepAlive);\n }\n }, 30_000);\n\n // Block until aborted — streamSSE closes when the callback returns\n await new Promise<void>((resolve) => {\n stream.onAbort(() => {\n aborted = true;\n clearInterval(keepAlive);\n cleanup();\n activeConnections.delete(sessionId);\n log.debug({ sessionId }, 'Event stream disconnected');\n resolve();\n });\n });\n });\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sse.js","names":[],"sources":["../../../../src/gateway/hono/sse.ts"],"sourcesContent":["import { streamSSE } from 'hono/streaming';\nimport type { Context } from 'hono';\nimport type { GatewayService } from '../service.js';\nimport { MAX_WEBCHAT_ATTACHMENT_FILE_BYTES } from '../chat-limits.js';\nimport { createLogger, updateAsyncLogContext } from '../../utils/logger.js';\nimport { stringifySSEData } from './sse-json.js';\nimport { resolveWebchatSessionKey } from '../resolve-webchat-session-key.js';\nimport type { UserTurnAttachment } from '../user-turn-input.js';\n\nconst log = createLogger('Gateway:SSE');\n\n// Active SSE connections tracking for connection limiting\nconst activeConnections = new Map<string, AbortController>();\n\nexport interface SSEHandlerConfig {\n service: GatewayService;\n maxSseConnections?: number;\n}\n\n// Type validation for agent request body\ninterface AgentRequestBody {\n message: string;\n channel?: string;\n sessionKey?: string;\n /** Epoch ms when the client started this send (abort cutoff / stale POST drop). */\n clientCreatedAtMs?: number;\n thinking?: string;\n attachments?: UserTurnAttachment[];\n}\n\nfunction isValidAgentRequest(body: unknown): body is AgentRequestBody {\n if (!body || typeof body !== 'object') return false;\n const b = body as Record<string, unknown>;\n // Allow empty message if attachments are provided\n const hasMessage = typeof b.message === 'string';\n const hasAttachments = Array.isArray(b.attachments) && b.attachments.length > 0;\n return hasMessage || hasAttachments;\n}\n\n/** Max base64 character length that can decode to `MAX_WEBCHAT_ATTACHMENT_FILE_BYTES`. */\nfunction maxBase64CharsForBinary(maxBinaryBytes: number): number {\n return 4 * Math.ceil(maxBinaryBytes / 3);\n}\n\n/**\n * POST /api/agent — Send a message to the agent, stream response via SSE.\n *\n * Request body: { message, channel?, sessionKey, attachments? }\n * Accept: text/event-stream → SSE stream\n * Accept: application/json → wait for full response, return JSON\n *\n * SSE events follow XOPC Chat Stream Protocol v1:\n * run_start, user_message, user_transcript, assistant_message_start,\n * assistant_delta, thinking_delta, thinking_end, tool_start, tool_update,\n * tool_end, review_start, review_delta, review_end, assistant_message_end,\n * compaction, tts_audio, clarify_request,\n * run_end, error.\n */\nexport function createAgentSSEHandler(config: SSEHandlerConfig) {\n const { service } = config;\n\n return async (c: Context) => {\n const body = await c.req.json().catch(() => null);\n\n // Input validation\n if (!isValidAgentRequest(body)) {\n return c.json({\n ok: false,\n error: { code: 'BAD_REQUEST', message: 'Missing required field: message or attachments' }\n }, 400);\n }\n\n const { message, channel = 'webchat', attachments, thinking } = body;\n const clientCreatedAtMs =\n typeof body.clientCreatedAtMs === 'number' && Number.isFinite(body.clientCreatedAtMs)\n ? body.clientCreatedAtMs\n : undefined;\n const resolved = resolveWebchatSessionKey({\n sessionKey: typeof body.sessionKey === 'string' ? body.sessionKey : undefined,\n });\n if (resolved.ok === false) {\n return c.json({\n ok: false,\n error: { code: 'BAD_REQUEST', message: resolved.error },\n }, 400);\n }\n const chatId = resolved.sessionKey;\n\n updateAsyncLogContext({ sessionKey: String(chatId) });\n\n if (Array.isArray(attachments)) {\n const maxDataChars = maxBase64CharsForBinary(MAX_WEBCHAT_ATTACHMENT_FILE_BYTES);\n for (const a of attachments) {\n if (!a || typeof a !== 'object') continue;\n const data = (a as { data?: unknown }).data;\n if (typeof data === 'string' && data.length > maxDataChars) {\n return c.json(\n {\n ok: false,\n error: {\n code: 'BAD_REQUEST',\n message: `Attachment exceeds maximum size (${MAX_WEBCHAT_ATTACHMENT_FILE_BYTES} bytes)`,\n },\n },\n 400,\n );\n }\n }\n }\n\n const accept = c.req.header('Accept') || '';\n const wantSSE = accept.includes('text/event-stream');\n\n const clientAbort = new AbortController();\n const raw = c.req.raw;\n // Keep webchat runs alive across transient disconnects (page refresh / tab route switch)\n // so the client can reattach via /api/agent/resume using runId from `run_start`.\n // Explicit cancellation still goes through /api/agent/abort.\n if (channel !== 'webchat') {\n if (raw.signal.aborted) {\n clientAbort.abort();\n } else {\n raw.signal.addEventListener('abort', () => clientAbort.abort(), { once: true });\n }\n }\n\n // --- Non-streaming fallback: collect everything, return JSON ---\n if (!wantSSE) {\n const jsonSessionKey = channel === 'webchat' ? chatId : undefined;\n\n const generator = service.runAgent(message, channel, chatId, attachments, thinking, {\n signal: clientAbort.signal,\n ...(clientCreatedAtMs !== undefined ? { clientCreatedAtMs } : {}),\n });\n try {\n let finalResult: { status: string; summary: string } | undefined;\n const tokens: string[] = [];\n\n while (true) {\n const { done, value } = await generator.next();\n if (done) {\n finalResult = value as { status: string; summary: string };\n break;\n }\n const chunk = value as { type: string; payload?: { delta?: unknown } };\n if (chunk.type === 'assistant_delta' && typeof chunk.payload?.delta === 'string') {\n tokens.push(chunk.payload.delta);\n }\n }\n\n return c.json({\n ok: true,\n payload: {\n ...finalResult,\n content: tokens.join(''),\n ...(jsonSessionKey !== undefined\n ? { sessionKey: jsonSessionKey, key: jsonSessionKey }\n : {}),\n },\n });\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.error(\n { err: error, errorMessage: em, phase: 'gateway.agent_run', sessionKey: jsonSessionKey, channel },\n `Agent run failed (JSON mode): ${em}`,\n );\n return c.json({\n ok: false,\n error: { code: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : 'Unknown error' },\n }, 500);\n }\n }\n\n // --- SSE streaming ---\n c.header('X-Accel-Buffering', 'no');\n return streamSSE(c, async (stream) => {\n if (channel !== 'webchat') {\n stream.onAbort(() => {\n clientAbort.abort();\n });\n }\n\n const generator = service.runAgent(message, channel, chatId, attachments, thinking, {\n signal: clientAbort.signal,\n ...(clientCreatedAtMs !== undefined ? { clientCreatedAtMs } : {}),\n });\n\n let eventId = 0;\n\n try {\n while (true) {\n const { done, value } = await generator.next();\n\n if (done) break;\n\n const chunk = value as { type: string; seq?: unknown };\n await stream.writeSSE({\n id: typeof chunk.seq === 'number' ? String(chunk.seq) : String(++eventId),\n event: chunk.type || 'message',\n data: stringifySSEData(chunk),\n });\n }\n } catch (error) {\n log.error({ err: error }, 'Agent run failed (SSE mode)');\n await stream.writeSSE({\n id: String(++eventId),\n event: 'error',\n data: stringifySSEData({\n type: 'error',\n runId: 'unknown',\n sessionKey: chatId,\n timestamp: Date.now(),\n payload: { code: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : 'Unknown error' },\n }),\n });\n }\n });\n };\n}\n\n/**\n * POST /api/agent/resume — Re-attach to an in-progress agent run via SSE.\n *\n * Request body: { runId, sessionKey }\n * The relay replays all buffered events from the beginning and then live-tails\n * until the run completes.\n *\n * SSE events are identical to those from POST /api/agent.\n */\nexport function createAgentResumeHandler(config: SSEHandlerConfig) {\n const { service } = config;\n\n return async (c: Context) => {\n const body = await c.req.json().catch(() => null);\n if (!body || typeof body !== 'object') {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Invalid JSON body' } }, 400);\n }\n\n const { runId, sessionKey } = body as { runId?: string; sessionKey?: string };\n if (typeof sessionKey === 'string' && sessionKey.trim()) {\n updateAsyncLogContext({ sessionKey: sessionKey.trim() });\n }\n if (!runId || typeof runId !== 'string') {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Missing required field: runId' } }, 400);\n }\n\n if (!service.runRelay.hasRun(runId)) {\n return c.json({ ok: false, error: { code: 'NOT_FOUND', message: 'Run not found or already expired' } }, 404);\n }\n\n c.header('X-Accel-Buffering', 'no');\n return streamSSE(c, async (stream) => {\n let eventId = 0;\n try {\n for await (const event of service.runRelay.subscribe(runId)) {\n await stream.writeSSE({\n id: typeof event.seq === 'number' ? String(event.seq) : String(++eventId),\n event: event.type || 'message',\n data: stringifySSEData(event),\n });\n }\n } catch (error) {\n log.error({ err: error, runId }, 'Resume stream failed');\n await stream.writeSSE({\n id: String(++eventId),\n event: 'error',\n data: stringifySSEData({\n type: 'error',\n runId,\n sessionKey: typeof sessionKey === 'string' ? sessionKey : '',\n timestamp: Date.now(),\n payload: { code: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : 'Unknown error' },\n }),\n });\n }\n });\n };\n}\n\n/**\n * POST /api/send — Send a message through a channel (non-streaming).\n */\nexport function createSendHandler(config: SSEHandlerConfig) {\n const { service } = config;\n\n return async (c: Context) => {\n const body = await c.req.json().catch(() => ({}));\n const channel = body.channel as string;\n const chatId = body.chatId as string;\n const content = body.content as string;\n\n if (!channel || !chatId || !content) {\n return c.json(\n { ok: false, error: { code: 'BAD_REQUEST', message: 'Missing required fields: channel, chatId, content' } },\n 400,\n );\n }\n\n try {\n const result = await service.sendMessage(channel, chatId, content);\n return c.json({ ok: true, payload: result });\n } catch (error) {\n log.error({ err: error }, 'Send failed');\n return c.json(\n { ok: false, error: { code: 'INTERNAL_ERROR', message: error instanceof Error ? error.message : 'Unknown error' } },\n 500,\n );\n }\n };\n}\n\n/**\n * GET /api/events — Server-pushed event stream (SSE).\n *\n * The client opens this long-lived connection to receive:\n * - channel status changes\n * - config reload notifications\n * - cron execution results\n * - any other server-initiated events\n *\n * Supports Last-Event-ID for reconnection.\n * Enforces maximum connection limit to prevent DoS.\n */\nexport function createEventsSSEHandler(config: SSEHandlerConfig) {\n const { service } = config;\n const maxConnections = config.maxSseConnections ?? 100;\n\n return async (c: Context) => {\n // Check maximum connections limit\n if (activeConnections.size >= maxConnections) {\n log.warn({ current: activeConnections.size, max: maxConnections }, 'SSE connection limit reached');\n return c.json({\n ok: false,\n error: { code: 'TOO_MANY_CONNECTIONS', message: 'Maximum SSE connections exceeded' }\n }, 503);\n }\n\n const lastEventId = c.req.header('Last-Event-ID') || undefined;\n const sessionId = c.req.header('X-Session-Id')\n || c.req.query('sessionId')\n || crypto.randomUUID();\n\n updateAsyncLogContext({ sessionId: String(sessionId) });\n\n const abortController = new AbortController();\n activeConnections.set(sessionId, abortController);\n\n return streamSSE(c, async (stream) => {\n let aborted = false;\n\n // Send a hello event so the client knows the stream is established\n await stream.writeSSE({\n id: '0',\n event: 'connected',\n data: JSON.stringify({ sessionId }),\n });\n\n // Subscribe to service events\n const cleanup = service.subscribe(sessionId, async (event) => {\n if (aborted) return;\n try {\n await stream.writeSSE({\n id: event.id,\n event: event.type,\n data: JSON.stringify(event.payload),\n });\n } catch {\n // Stream closed, will be cleaned up by onAbort\n }\n });\n\n // Replay missed events on reconnect\n if (lastEventId) {\n const missed = service.getEventsSince(sessionId, lastEventId);\n for (const event of missed) {\n await stream.writeSSE({\n id: event.id,\n event: event.type,\n data: JSON.stringify(event.payload),\n });\n }\n }\n\n // Keep alive with periodic comments (every 30s)\n const keepAlive = setInterval(async () => {\n if (aborted) { clearInterval(keepAlive); return; }\n try {\n await stream.writeSSE({ event: 'ping', data: '' });\n } catch {\n clearInterval(keepAlive);\n }\n }, 30_000);\n\n // Block until aborted — streamSSE closes when the callback returns\n await new Promise<void>((resolve) => {\n stream.onAbort(() => {\n aborted = true;\n clearInterval(keepAlive);\n cleanup();\n activeConnections.delete(sessionId);\n log.debug({ sessionId }, 'Event stream disconnected');\n resolve();\n });\n });\n });\n };\n}\n"],"mappings":"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"}
|
package/dist/src/gateway/lock.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import net from "node:net";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
import { execFileSync } from "node:child_process";
|
|
5
|
-
import net from "node:net";
|
|
6
6
|
//#region src/gateway/ports.ts
|
|
7
7
|
/**
|
|
8
8
|
* Ports Management - Port management utilities
|
|
@@ -51,6 +51,18 @@ export interface SkillSourceInstallResultPayload extends SkillInstallResultPaylo
|
|
|
51
51
|
kind: HubPullResult['kind'];
|
|
52
52
|
contentHash: string;
|
|
53
53
|
}
|
|
54
|
+
export interface ExtensionMarketplacePackageDetailPayload extends MarketplacePackageDetail {
|
|
55
|
+
installability: {
|
|
56
|
+
available: boolean;
|
|
57
|
+
reason?: string;
|
|
58
|
+
sha256?: string;
|
|
59
|
+
};
|
|
60
|
+
manifest?: Record<string, unknown>;
|
|
61
|
+
packageSummary?: {
|
|
62
|
+
dependencyCount: number;
|
|
63
|
+
lifecycleScripts: string[];
|
|
64
|
+
};
|
|
65
|
+
}
|
|
54
66
|
export declare class GatewayMarketplaceService {
|
|
55
67
|
private readonly opts;
|
|
56
68
|
constructor(opts: GatewayMarketplaceServiceOptions);
|
|
@@ -95,7 +107,7 @@ export declare class GatewayMarketplaceService {
|
|
|
95
107
|
private getDefaultAgentId;
|
|
96
108
|
private getInstallAvailability;
|
|
97
109
|
/** xopc-store extension package preview (type must be `extension`). */
|
|
98
|
-
fetchExtensionPackageDetail(packageName: string): Promise<
|
|
110
|
+
fetchExtensionPackageDetail(packageName: string): Promise<ExtensionMarketplacePackageDetailPayload>;
|
|
99
111
|
/**
|
|
100
112
|
* Install an extension from xopc-store into `~/.xopc/extensions`, append id
|
|
101
113
|
* to `extensions.enabled`, refresh the loader, and emit `config.reload`.
|
|
@@ -8,8 +8,7 @@ import { normalizeSkillInstallTarget } from "../../agent/skills/install-target.j
|
|
|
8
8
|
import { removeSkillsLockEntry } from "../../agent/skills/hub-lock.js";
|
|
9
9
|
import { deleteManagedSkill, installSkillFromZip, listManagedSkillDirs } from "../../agent/skills/managed-store.js";
|
|
10
10
|
import { getExtensionLockfileManager } from "../../extensions/lockfile.js";
|
|
11
|
-
import {
|
|
12
|
-
import { existsSync, mkdirSync, rmSync } from "node:fs";
|
|
11
|
+
import { existsSync, rmSync } from "node:fs";
|
|
13
12
|
//#region src/gateway/service/marketplace-service.ts
|
|
14
13
|
/**
|
|
15
14
|
* GatewayMarketplaceService — install / browse / remove for the two marketplaces
|
|
@@ -190,10 +189,49 @@ var GatewayMarketplaceService = class {
|
|
|
190
189
|
}
|
|
191
190
|
/** xopc-store extension package preview (type must be `extension`). */
|
|
192
191
|
async fetchExtensionPackageDetail(packageName) {
|
|
193
|
-
const { fetchMarketplacePackageDetail, resolveExtensionsStoreBaseUrl } = await import("../../agent/skills/marketplace/adapters/store/store-api-client.js");
|
|
194
|
-
const
|
|
192
|
+
const { downloadExtensionStoreZipBuffer, fetchMarketplacePackageDetail, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl, verifyStoreArtifactSha256 } = await import("../../agent/skills/marketplace/adapters/store/store-api-client.js");
|
|
193
|
+
const base = resolveExtensionsStoreBaseUrl(this.opts.getConfig());
|
|
194
|
+
const detail = await fetchMarketplacePackageDetail(base, packageName.trim());
|
|
195
195
|
if (detail.type !== "extension") throw new Error(`Package "${packageName}" is not an extension (store type: ${detail.type}).`);
|
|
196
|
-
|
|
196
|
+
try {
|
|
197
|
+
const resolved = await resolveExtensionZipDownloadUrl(base, packageName.trim());
|
|
198
|
+
const buffer = await downloadExtensionStoreZipBuffer(base, resolved.downloadUrl);
|
|
199
|
+
verifyStoreArtifactSha256(buffer, resolved.sha256);
|
|
200
|
+
const { peekExtensionManifestFromStoreZip, peekExtensionPackageJsonFromStoreZip } = await import("../../extensions/install.js");
|
|
201
|
+
const manifest = peekExtensionManifestFromStoreZip(buffer);
|
|
202
|
+
const packageJson = peekExtensionPackageJsonFromStoreZip(buffer);
|
|
203
|
+
const dependencies = packageJson?.dependencies;
|
|
204
|
+
const dependencyCount = dependencies && typeof dependencies === "object" && !Array.isArray(dependencies) ? Object.keys(dependencies).length : 0;
|
|
205
|
+
const scripts = packageJson?.scripts;
|
|
206
|
+
const lifecycleNames = new Set([
|
|
207
|
+
"preinstall",
|
|
208
|
+
"install",
|
|
209
|
+
"postinstall",
|
|
210
|
+
"prepare"
|
|
211
|
+
]);
|
|
212
|
+
const lifecycleScripts = scripts && typeof scripts === "object" && !Array.isArray(scripts) ? Object.keys(scripts).filter((name) => lifecycleNames.has(name)) : [];
|
|
213
|
+
return {
|
|
214
|
+
...detail,
|
|
215
|
+
installability: {
|
|
216
|
+
available: true,
|
|
217
|
+
sha256: resolved.sha256
|
|
218
|
+
},
|
|
219
|
+
...manifest ? { manifest } : {},
|
|
220
|
+
packageSummary: {
|
|
221
|
+
dependencyCount,
|
|
222
|
+
lifecycleScripts
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
} catch (err) {
|
|
226
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
227
|
+
return {
|
|
228
|
+
...detail,
|
|
229
|
+
installability: {
|
|
230
|
+
available: false,
|
|
231
|
+
reason
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
197
235
|
}
|
|
198
236
|
/**
|
|
199
237
|
* Install an extension from xopc-store into `~/.xopc/extensions`, append id
|
|
@@ -206,60 +244,78 @@ var GatewayMarketplaceService = class {
|
|
|
206
244
|
if (!packageName) throw new Error("Package name is required");
|
|
207
245
|
const cfg = this.opts.getConfig();
|
|
208
246
|
const { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl, verifyStoreArtifactSha256 } = await import("../../agent/skills/marketplace/adapters/store/store-api-client.js");
|
|
209
|
-
const {
|
|
247
|
+
const { commitStagedExtensionInstall, finalizeStagedExtensionInstall, rollbackStagedExtensionInstall, stageExtensionStoreZip } = await import("../../extensions/install-transaction.js");
|
|
210
248
|
const storeBase = resolveExtensionsStoreBaseUrl(cfg);
|
|
211
249
|
const targetDir = resolveExtensionsDir();
|
|
212
|
-
mkdirSync(targetDir, { recursive: true });
|
|
213
250
|
const { downloadUrl, version, sha256 } = await resolveExtensionZipDownloadUrl(storeBase, packageName, opts.version);
|
|
214
251
|
const buf = await downloadExtensionStoreZipBuffer(storeBase, downloadUrl);
|
|
215
252
|
verifyStoreArtifactSha256(buf, sha256);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
253
|
+
const transaction = await stageExtensionStoreZip(buf, targetDir);
|
|
254
|
+
const lock = getExtensionLockfileManager();
|
|
255
|
+
const lockSnapshot = await lock.load();
|
|
256
|
+
let configSaved = false;
|
|
257
|
+
let lockWriteStarted = false;
|
|
258
|
+
try {
|
|
259
|
+
commitStagedExtensionInstall(transaction, opts.overwrite ?? false);
|
|
260
|
+
const nextConfig = this.mergeExtensionEnabledIntoConfig(cfg, transaction.extensionId);
|
|
261
|
+
const saved = await this.opts.saveConfig(nextConfig);
|
|
262
|
+
if (!saved.saved) throw new Error(saved.error ?? "Failed to save config after extension install");
|
|
263
|
+
configSaved = true;
|
|
264
|
+
lockWriteStarted = true;
|
|
265
|
+
await lock.upsert(transaction.extensionId, {
|
|
266
|
+
name: transaction.extensionId,
|
|
267
|
+
version,
|
|
268
|
+
resolved: packageName,
|
|
269
|
+
artifactUrl: downloadUrl,
|
|
270
|
+
source: "store"
|
|
221
271
|
});
|
|
272
|
+
} catch (err) {
|
|
273
|
+
const em = err instanceof Error ? err.message : String(err);
|
|
274
|
+
const rollbackErrors = [];
|
|
275
|
+
try {
|
|
276
|
+
rollbackStagedExtensionInstall(transaction);
|
|
277
|
+
} catch (rollbackErr) {
|
|
278
|
+
rollbackErrors.push(`files: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);
|
|
279
|
+
}
|
|
280
|
+
if (configSaved) try {
|
|
281
|
+
const restored = await this.opts.saveConfig(cfg);
|
|
282
|
+
if (!restored.saved) rollbackErrors.push(`config: ${restored.error ?? "restore failed"}`);
|
|
283
|
+
} catch (rollbackErr) {
|
|
284
|
+
rollbackErrors.push(`config: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);
|
|
285
|
+
}
|
|
286
|
+
if (lockWriteStarted) try {
|
|
287
|
+
await lock.save(lockSnapshot);
|
|
288
|
+
} catch (rollbackErr) {
|
|
289
|
+
rollbackErrors.push(`lockfile: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);
|
|
290
|
+
}
|
|
291
|
+
const rollbackSuffix = rollbackErrors.length > 0 ? ` Rollback incomplete (${rollbackErrors.join("; ")}).` : "";
|
|
292
|
+
log.error({
|
|
293
|
+
err,
|
|
294
|
+
errorMessage: em,
|
|
295
|
+
extensionId: transaction.extensionId,
|
|
296
|
+
rollbackErrors
|
|
297
|
+
}, `Marketplace extension install failed: ${em}${rollbackSuffix}`);
|
|
298
|
+
throw new Error(`${em}${rollbackSuffix}`, { cause: err });
|
|
222
299
|
}
|
|
223
|
-
const result = await installExtensionFromStoreZip(buf, targetDir);
|
|
224
|
-
if (!result.ok || !result.extensionId) throw new Error(result.error ?? "Extension install failed");
|
|
225
|
-
await getExtensionLockfileManager().upsert(result.extensionId, {
|
|
226
|
-
name: result.extensionId,
|
|
227
|
-
version,
|
|
228
|
-
resolved: packageName,
|
|
229
|
-
source: "store"
|
|
230
|
-
});
|
|
231
|
-
const nextConfig = this.mergeExtensionEnabledIntoConfig(cfg, result.extensionId);
|
|
232
|
-
const saved = await this.opts.saveConfig(nextConfig);
|
|
233
|
-
if (!saved.saved) throw new Error(saved.error ?? "Failed to save config after extension install");
|
|
234
|
-
const channelIdsBefore = new Set(this.opts.getChannelManager().getAllPlugins().map((p) => p.id));
|
|
235
|
-
let requiresGatewayRestart = false;
|
|
236
|
-
const loader = this.opts.getExtensionLoader();
|
|
237
300
|
try {
|
|
238
|
-
|
|
239
|
-
loader.invalidateManifestCache();
|
|
240
|
-
await loader.loadByActivationPlan();
|
|
241
|
-
const reg = loader.getRegistry();
|
|
242
|
-
for (const p of reg.channelPlugins) if (!channelIdsBefore.has(p.id)) {
|
|
243
|
-
requiresGatewayRestart = true;
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
301
|
+
finalizeStagedExtensionInstall(transaction);
|
|
247
302
|
} catch (err) {
|
|
248
303
|
const em = err instanceof Error ? err.message : String(err);
|
|
249
304
|
log.warn({
|
|
250
305
|
err,
|
|
251
|
-
errorMessage: em
|
|
252
|
-
|
|
253
|
-
|
|
306
|
+
errorMessage: em,
|
|
307
|
+
extensionId: transaction.extensionId
|
|
308
|
+
}, `Installed extension but temporary backup cleanup failed: ${em}`);
|
|
254
309
|
}
|
|
310
|
+
this.opts.getExtensionLoader()?.invalidateManifestCache();
|
|
255
311
|
this.opts.emit("config.reload", {
|
|
256
312
|
section: "extensions",
|
|
257
313
|
source: "marketplace-install"
|
|
258
314
|
});
|
|
259
315
|
return {
|
|
260
|
-
extensionId:
|
|
316
|
+
extensionId: transaction.extensionId,
|
|
261
317
|
version,
|
|
262
|
-
requiresGatewayRestart
|
|
318
|
+
requiresGatewayRestart: true
|
|
263
319
|
};
|
|
264
320
|
}
|
|
265
321
|
/** Remove a user-installed extension (global or per-agent dir) from disk and config. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketplace-service.js","names":[],"sources":["../../../../src/gateway/service/marketplace-service.ts"],"sourcesContent":["/**\n * GatewayMarketplaceService — install / browse / remove for the two marketplaces\n * the gateway exposes:\n *\n * • **Skills** (`~/.xopc/skills/managed/<id>`) — zip-bundled markdown skills\n * pulled from a provider catalog (`agent/skills/skills-marketplace.ts`).\n * • **Extensions** (`~/.xopc/extensions/<id>`) — full extension packages from\n * the xopc-store.\n *\n * Owns the install/uninstall composite operations:\n * - download zip → unpack → upsert lockfile → refresh loader → emit reload\n * - rm dir → remove from `extensions.enabled` → refresh loader → emit reload\n *\n * Local-only skill management (install-from-zip, delete, enable/disable, list)\n * lives here too so callers (commands-skills routes) depend on a single narrow\n * service instead of the full `GatewayService`.\n */\nimport { existsSync, mkdirSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport type { Config } from '../../config/schema.js';\nimport type { AgentService } from '../../agent/service.js';\nimport type { ChannelManager } from '../../channels/manager.js';\nimport type { ExtensionLoader } from '../../extensions/loader.js';\nimport type {\n AgentSkillAvailabilityEntry,\n AgentSkillAvailabilityPayload,\n SkillCatalogEntry,\n SkillCatalogRuntimeMeta,\n} from '../../agent/agent-manager.js';\nimport type {\n ManagedSkillListItem,\n} from '../../agent/skills/managed-store.js';\nimport type { SkillMarkdownPreviewPayload } from '../../agent/skills/types.js';\nimport type {\n MarketplaceCategoryOption,\n SkillsStoreListParams,\n UnifiedMarketplaceListResponse,\n UnifiedMarketplacePackageDetail,\n} from '../../agent/skills/skills-marketplace.js';\nimport type { MarketplacePackageDetail } from '../../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport {\n deleteManagedSkill as deleteManagedSkillDir,\n installSkillFromZip,\n listManagedSkillDirs,\n} from '../../agent/skills/managed-store.js';\nimport { createSkillConfigManager } from '../../agent/skills/config.js';\nimport { removeSkillsLockEntry } from '../../agent/skills/hub-lock.js';\nimport type { HubPullResult } from '../../agent/skills/hub-pull.js';\nimport {\n normalizeSkillInstallTarget,\n type SkillInstallTarget,\n} from '../../agent/skills/install-target.js';\nimport {\n resolveWorkspaceSkillsDir,\n resolveWorkspaceSkillsLockPath,\n} from '../../agent/skills/workspace-skills-dir.js';\nimport { getExtensionLockfileManager } from '../../extensions/lockfile.js';\nimport { resolveExtensionsDir, resolveStateDir } from '../../config/paths.js';\nimport { createLogger } from '../../utils/logger.js';\n\nconst log = createLogger('Gateway:Marketplace');\n\nexport interface GatewayMarketplaceServiceOptions {\n getConfig: () => Config;\n getAgentService: () => AgentService;\n getExtensionLoader: () => ExtensionLoader | null;\n getChannelManager: () => ChannelManager;\n getWorkspacePath: () => string;\n saveConfig: (config: Config) => Promise<{ saved: boolean; error?: string }>;\n emit: (type: string, payload: unknown) => void;\n}\n\nexport interface SkillInstallAvailability {\n skillId: string;\n skillName?: string;\n loaded: boolean;\n enabled?: boolean;\n defaultAgentId: string;\n availableForDefaultAgent?: boolean;\n unavailableReason?: AgentSkillAvailabilityEntry['unavailableReason'];\n diagnostics: SkillCatalogRuntimeMeta['diagnostics'];\n}\n\nexport interface SkillInstallResultPayload {\n skillId: string;\n path: string;\n target?: SkillInstallTarget;\n availability: SkillInstallAvailability;\n}\n\nexport interface SkillSourceInstallOptions {\n source: string;\n ref?: string;\n path?: string;\n skillId?: string;\n target?: SkillInstallTarget;\n force?: boolean;\n strictScan?: boolean;\n}\n\nexport interface SkillSourceInstallResultPayload extends SkillInstallResultPayload {\n source: string;\n kind: HubPullResult['kind'];\n contentHash: string;\n}\n\nexport class GatewayMarketplaceService {\n private readonly opts: GatewayMarketplaceServiceOptions;\n\n constructor(opts: GatewayMarketplaceServiceOptions) {\n this.opts = opts;\n }\n\n private resolveInstallTarget(target: unknown): {\n target: SkillInstallTarget;\n rootDir?: string;\n lockPath?: string;\n } {\n const normalized = normalizeSkillInstallTarget(target);\n if (normalized === 'global') {\n return { target: normalized };\n }\n const workspace = this.opts.getWorkspacePath();\n return {\n target: normalized,\n rootDir: resolveWorkspaceSkillsDir(workspace),\n lockPath: resolveWorkspaceSkillsLockPath(workspace),\n };\n }\n\n // ── Local skills (managed dir) ────────────────────────────────────────\n\n getSkillsApi(): {\n catalog: SkillCatalogEntry[];\n managed: ManagedSkillListItem[];\n } & SkillCatalogRuntimeMeta {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n return {\n catalog: snapshot.catalog,\n managed: listManagedSkillDirs(),\n version: snapshot.version,\n loadedAt: snapshot.loadedAt,\n diagnostics: snapshot.diagnostics,\n status: snapshot.status,\n };\n }\n\n getSkillsStatusApi(): SkillCatalogRuntimeMeta {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n return {\n version: snapshot.version,\n loadedAt: snapshot.loadedAt,\n diagnostics: snapshot.diagnostics,\n status: snapshot.status,\n };\n }\n\n getAgentSkillsApi(agentId: string): AgentSkillAvailabilityPayload {\n return this.opts.getAgentService().getAgentSkillAvailability(agentId);\n }\n\n getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null {\n return this.opts.getAgentService().getSkillMarkdownSource(skillName);\n }\n\n deleteSkill(skillId: string, target?: SkillInstallTarget): void {\n const requestedTarget = target ? this.resolveInstallTarget(target) : undefined;\n const workspaceTarget = requestedTarget ?? this.resolveInstallTarget('workspace');\n try {\n removeSkillsLockEntry(skillId, workspaceTarget.lockPath);\n deleteManagedSkillDir(skillId, workspaceTarget.rootDir);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n return;\n } catch (err) {\n if (requestedTarget || !(err instanceof Error) || !err.message.includes('Skill not found')) {\n throw err;\n }\n }\n\n removeSkillsLockEntry(skillId);\n deleteManagedSkillDir(skillId);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n }\n\n installSkillZip(\n buffer: Buffer,\n opts: { skillId?: string; overwrite?: boolean; target?: SkillInstallTarget },\n ): SkillInstallResultPayload {\n const target = this.resolveInstallTarget(opts.target);\n const result = installSkillFromZip(buffer, {\n skillId: opts.skillId,\n overwrite: opts.overwrite,\n rootDir: target.rootDir,\n });\n removeSkillsLockEntry(result.skillId, target.lockPath);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n return {\n ...result,\n target: target.target,\n availability: this.getInstallAvailability(result.skillId),\n };\n }\n\n reloadSkills(): void {\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n }\n\n patchSkillEnabled(skillName: string, enabled: boolean): void {\n createSkillConfigManager(resolveStateDir()).setSkillEnabled(skillName, enabled);\n this.opts.getAgentService().refreshSkillsAfterSkillConfigChange();\n }\n\n // ── Skills marketplace catalog ────────────────────────────────────────\n\n async fetchSkillsCatalog(\n params: SkillsStoreListParams,\n provider?: string,\n ): Promise<UnifiedMarketplaceListResponse> {\n const { listMarketplacePackages } = await import('../../agent/skills/skills-marketplace.js');\n return listMarketplacePackages(this.opts.getConfig(), params, provider);\n }\n\n async fetchSkillsCategories(\n provider?: string,\n ): Promise<{ items: MarketplaceCategoryOption[] }> {\n const { listMarketplaceCategories } = await import('../../agent/skills/skills-marketplace.js');\n return listMarketplaceCategories(this.opts.getConfig(), provider);\n }\n\n async fetchSkillsPackageDetail(\n packageName: string,\n provider?: string,\n ): Promise<UnifiedMarketplacePackageDetail> {\n const { getMarketplacePackageDetail } = await import('../../agent/skills/skills-marketplace.js');\n return getMarketplacePackageDetail(this.opts.getConfig(), packageName, provider);\n }\n\n async installSkill(opts: {\n name: string;\n version?: string;\n overwrite?: boolean;\n provider?: string;\n target?: SkillInstallTarget;\n }): Promise<SkillInstallResultPayload> {\n const { downloadFromMarketplace } = await import('../../agent/skills/skills-marketplace.js');\n const { buffer, skillId } = await downloadFromMarketplace(\n this.opts.getConfig(),\n opts.name,\n opts.version,\n opts.provider,\n );\n return this.installSkillZip(buffer, {\n skillId,\n overwrite: opts.overwrite ?? false,\n target: opts.target,\n });\n }\n\n async installSkillFromSource(\n opts: SkillSourceInstallOptions,\n ): Promise<SkillSourceInstallResultPayload> {\n const result = await this.opts.getAgentService().installSkillFromSource({\n source: opts.source,\n ref: opts.ref,\n path: opts.path,\n skillId: opts.skillId,\n target: opts.target,\n workspace: this.opts.getWorkspacePath(),\n force: opts.force ?? false,\n strictScan: opts.strictScan ?? false,\n });\n return {\n skillId: result.skillId,\n path: result.path,\n target: result.target,\n source: result.source,\n kind: result.kind,\n contentHash: result.contentHash,\n availability: this.getInstallAvailability(result.skillId),\n };\n }\n\n async getSkillsProvider(): Promise<{ provider: string; displayName: string }> {\n const {\n getMarketplaceProviderDisplayName,\n resolveSkillsMarketplaceProvider,\n } = await import('../../agent/skills/skills-marketplace.js');\n const provider = resolveSkillsMarketplaceProvider(this.opts.getConfig());\n return {\n provider,\n displayName: getMarketplaceProviderDisplayName(provider),\n };\n }\n\n /** All registered marketplace providers (built-in + extension-contributed). */\n async getSkillsProviders(): Promise<Array<{ id: string; displayName: string }>> {\n const { listRegisteredProviders } = await import('../../agent/skills/skills-marketplace.js');\n return listRegisteredProviders();\n }\n\n private getDefaultAgentId(): string {\n return this.opts.getConfig().agents?.default || 'main';\n }\n\n private getInstallAvailability(skillId: string): SkillInstallAvailability {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n const catalogEntry =\n snapshot.catalog.find((s) => s.directoryId === skillId) ??\n snapshot.catalog.find((s) => s.name === skillId);\n const defaultAgentId = this.getDefaultAgentId();\n const agentSkills = this.getAgentSkillsApi(defaultAgentId);\n const agentEntry = catalogEntry\n ? agentSkills.skills.find((s) => s.name === catalogEntry.name)\n : undefined;\n const relevantDiagnostics = snapshot.diagnostics.filter((diag) => {\n if (!catalogEntry) return diag.path?.includes(skillId) || diag.skillName === skillId;\n return diag.skillName === catalogEntry.name || diag.path?.startsWith(catalogEntry.path);\n });\n return {\n skillId,\n ...(catalogEntry ? { skillName: catalogEntry.name } : {}),\n loaded: Boolean(catalogEntry),\n ...(catalogEntry ? { enabled: catalogEntry.enabled } : {}),\n defaultAgentId,\n ...(agentEntry ? { availableForDefaultAgent: agentEntry.availableForCurrentAgent } : {}),\n ...(agentEntry?.unavailableReason ? { unavailableReason: agentEntry.unavailableReason } : {}),\n diagnostics: relevantDiagnostics,\n };\n }\n\n // ── Extension marketplace ─────────────────────────────────────────────\n\n /** xopc-store extension package preview (type must be `extension`). */\n async fetchExtensionPackageDetail(packageName: string): Promise<MarketplacePackageDetail> {\n const {\n fetchMarketplacePackageDetail,\n resolveExtensionsStoreBaseUrl,\n } = await import('../../agent/skills/marketplace/adapters/store/store-api-client.js');\n const base = resolveExtensionsStoreBaseUrl(this.opts.getConfig());\n const detail = await fetchMarketplacePackageDetail(base, packageName.trim());\n if (detail.type !== 'extension') {\n throw new Error(\n `Package \"${packageName}\" is not an extension (store type: ${detail.type}).`,\n );\n }\n return detail;\n }\n\n /**\n * Install an extension from xopc-store into `~/.xopc/extensions`, append id\n * to `extensions.enabled`, refresh the loader, and emit `config.reload`.\n * Returns `requiresGatewayRestart=true` when a new channel plugin would have\n * to wire into the running gateway (channel registration cannot hot-patch).\n */\n async installExtension(opts: {\n name: string;\n version?: string;\n overwrite?: boolean;\n }): Promise<{ extensionId: string; version: string; requiresGatewayRestart: boolean }> {\n const packageName = opts.name.trim();\n if (!packageName) {\n throw new Error('Package name is required');\n }\n const cfg = this.opts.getConfig();\n const {\n downloadExtensionStoreZipBuffer,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n verifyStoreArtifactSha256,\n } = await import('../../agent/skills/marketplace/adapters/store/store-api-client.js');\n const {\n installExtensionFromStoreZip,\n peekExtensionIdFromStoreZip,\n } = await import('../../extensions/install.js');\n const storeBase = resolveExtensionsStoreBaseUrl(cfg);\n const targetDir = resolveExtensionsDir();\n mkdirSync(targetDir, { recursive: true });\n\n const { downloadUrl, version, sha256 } = await resolveExtensionZipDownloadUrl(\n storeBase,\n packageName,\n opts.version,\n );\n const buf = await downloadExtensionStoreZipBuffer(storeBase, downloadUrl);\n verifyStoreArtifactSha256(buf, sha256);\n\n if (opts.overwrite) {\n const peekId = peekExtensionIdFromStoreZip(buf);\n if (peekId && existsSync(join(targetDir, peekId))) {\n rmSync(join(targetDir, peekId), { recursive: true, force: true });\n }\n }\n\n const result = await installExtensionFromStoreZip(buf, targetDir);\n if (!result.ok || !result.extensionId) {\n throw new Error(result.error ?? 'Extension install failed');\n }\n\n const lock = getExtensionLockfileManager();\n await lock.upsert(result.extensionId, {\n name: result.extensionId,\n version,\n resolved: packageName,\n source: 'store',\n });\n\n const nextConfig = this.mergeExtensionEnabledIntoConfig(cfg, result.extensionId);\n const saved = await this.opts.saveConfig(nextConfig);\n if (!saved.saved) {\n throw new Error(saved.error ?? 'Failed to save config after extension install');\n }\n\n const channelIdsBefore = new Set(this.opts.getChannelManager().getAllPlugins().map((p) => p.id));\n let requiresGatewayRestart = false;\n const loader = this.opts.getExtensionLoader();\n try {\n if (loader) {\n loader.invalidateManifestCache();\n await loader.loadByActivationPlan();\n const reg = loader.getRegistry();\n for (const p of reg.channelPlugins) {\n if (!channelIdsBefore.has(p.id)) {\n requiresGatewayRestart = true;\n break;\n }\n }\n }\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Extension loader refresh after marketplace install failed: ${em}`);\n requiresGatewayRestart = true;\n }\n\n this.opts.emit('config.reload', { section: 'extensions', source: 'marketplace-install' });\n return { extensionId: result.extensionId, version, requiresGatewayRestart };\n }\n\n /** Remove a user-installed extension (global or per-agent dir) from disk and config. */\n async uninstallExtension(extensionId: string): Promise<{ requiresGatewayRestart: boolean }> {\n const id = extensionId.trim();\n if (!id) {\n throw new Error('extensionId is required');\n }\n const loader = this.opts.getExtensionLoader();\n if (!loader) {\n throw new Error('Extensions unavailable');\n }\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === id);\n if (!ext) {\n throw new Error(`Extension not found: ${id}`);\n }\n if (ext.source === 'bundled') {\n throw new Error('Built-in extensions cannot be uninstalled from the marketplace UI');\n }\n if (existsSync(ext.path)) {\n rmSync(ext.path, { recursive: true, force: true });\n }\n await getExtensionLockfileManager().remove(id);\n\n const nextConfig = this.mergeExtensionRemovedFromEnabledConfig(this.opts.getConfig(), id);\n const saved = await this.opts.saveConfig(nextConfig);\n if (!saved.saved) {\n throw new Error(saved.error ?? 'Failed to save config after extension uninstall');\n }\n try {\n loader.invalidateManifestCache();\n await loader.loadByActivationPlan();\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Extension loader refresh after uninstall failed: ${em}`);\n }\n this.opts.emit('config.reload', { section: 'extensions', source: 'marketplace-uninstall' });\n return { requiresGatewayRestart: true };\n }\n\n // ── Internals ─────────────────────────────────────────────────────────\n\n private mergeExtensionEnabledIntoConfig(currentConfig: Config, extensionId: string): Config {\n const id = extensionId.trim();\n const prevExt = currentConfig.extensions;\n const baseExt =\n prevExt && typeof prevExt === 'object' && !Array.isArray(prevExt)\n ? { ...(prevExt as Record<string, unknown>) }\n : {};\n const enabledRaw = baseExt.enabled;\n const enabled = Array.isArray(enabledRaw)\n ? [...enabledRaw.filter((x): x is string => typeof x === 'string')]\n : [];\n if (!enabled.includes(id)) enabled.push(id);\n\n const disabledRaw = baseExt.disabled;\n const nextExt: Record<string, unknown> = { ...baseExt, enabled };\n if (Array.isArray(disabledRaw)) {\n const next = disabledRaw.filter((x): x is string => typeof x === 'string' && x !== id);\n if (next.length > 0) nextExt.disabled = next;\n else delete nextExt.disabled;\n }\n\n return {\n ...currentConfig,\n extensions: nextExt,\n } as Config;\n }\n\n private mergeExtensionRemovedFromEnabledConfig(currentConfig: Config, extensionId: string): Config {\n const id = extensionId.trim();\n const prevExt = currentConfig.extensions;\n const baseExt =\n prevExt && typeof prevExt === 'object' && !Array.isArray(prevExt)\n ? { ...(prevExt as Record<string, unknown>) }\n : {};\n const enabledRaw = baseExt.enabled;\n const enabled = Array.isArray(enabledRaw)\n ? enabledRaw.filter((x): x is string => typeof x === 'string' && x !== id)\n : [];\n return {\n ...currentConfig,\n extensions: { ...baseExt, enabled },\n } as Config;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"marketplace-service.js","names":[],"sources":["../../../../src/gateway/service/marketplace-service.ts"],"sourcesContent":["/**\n * GatewayMarketplaceService — install / browse / remove for the two marketplaces\n * the gateway exposes:\n *\n * • **Skills** (`~/.xopc/skills/managed/<id>`) — zip-bundled markdown skills\n * pulled from a provider catalog (`agent/skills/skills-marketplace.ts`).\n * • **Extensions** (`~/.xopc/extensions/<id>`) — full extension packages from\n * the xopc-store.\n *\n * Owns the install/uninstall composite operations:\n * - download zip → unpack → upsert lockfile → refresh loader → emit reload\n * - rm dir → remove from `extensions.enabled` → refresh loader → emit reload\n *\n * Local-only skill management (install-from-zip, delete, enable/disable, list)\n * lives here too so callers (commands-skills routes) depend on a single narrow\n * service instead of the full `GatewayService`.\n */\nimport { existsSync, rmSync } from 'node:fs';\n\nimport type { Config } from '../../config/schema.js';\nimport type { AgentService } from '../../agent/service.js';\nimport type { ChannelManager } from '../../channels/manager.js';\nimport type { ExtensionLoader } from '../../extensions/loader.js';\nimport type {\n AgentSkillAvailabilityEntry,\n AgentSkillAvailabilityPayload,\n SkillCatalogEntry,\n SkillCatalogRuntimeMeta,\n} from '../../agent/agent-manager.js';\nimport type {\n ManagedSkillListItem,\n} from '../../agent/skills/managed-store.js';\nimport type { SkillMarkdownPreviewPayload } from '../../agent/skills/types.js';\nimport type {\n MarketplaceCategoryOption,\n SkillsStoreListParams,\n UnifiedMarketplaceListResponse,\n UnifiedMarketplacePackageDetail,\n} from '../../agent/skills/skills-marketplace.js';\nimport type { MarketplacePackageDetail } from '../../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport {\n deleteManagedSkill as deleteManagedSkillDir,\n installSkillFromZip,\n listManagedSkillDirs,\n} from '../../agent/skills/managed-store.js';\nimport { createSkillConfigManager } from '../../agent/skills/config.js';\nimport { removeSkillsLockEntry } from '../../agent/skills/hub-lock.js';\nimport type { HubPullResult } from '../../agent/skills/hub-pull.js';\nimport {\n normalizeSkillInstallTarget,\n type SkillInstallTarget,\n} from '../../agent/skills/install-target.js';\nimport {\n resolveWorkspaceSkillsDir,\n resolveWorkspaceSkillsLockPath,\n} from '../../agent/skills/workspace-skills-dir.js';\nimport { getExtensionLockfileManager } from '../../extensions/lockfile.js';\nimport { resolveExtensionsDir, resolveStateDir } from '../../config/paths.js';\nimport { createLogger } from '../../utils/logger.js';\n\nconst log = createLogger('Gateway:Marketplace');\n\nexport interface GatewayMarketplaceServiceOptions {\n getConfig: () => Config;\n getAgentService: () => AgentService;\n getExtensionLoader: () => ExtensionLoader | null;\n getChannelManager: () => ChannelManager;\n getWorkspacePath: () => string;\n saveConfig: (config: Config) => Promise<{ saved: boolean; error?: string }>;\n emit: (type: string, payload: unknown) => void;\n}\n\nexport interface SkillInstallAvailability {\n skillId: string;\n skillName?: string;\n loaded: boolean;\n enabled?: boolean;\n defaultAgentId: string;\n availableForDefaultAgent?: boolean;\n unavailableReason?: AgentSkillAvailabilityEntry['unavailableReason'];\n diagnostics: SkillCatalogRuntimeMeta['diagnostics'];\n}\n\nexport interface SkillInstallResultPayload {\n skillId: string;\n path: string;\n target?: SkillInstallTarget;\n availability: SkillInstallAvailability;\n}\n\nexport interface SkillSourceInstallOptions {\n source: string;\n ref?: string;\n path?: string;\n skillId?: string;\n target?: SkillInstallTarget;\n force?: boolean;\n strictScan?: boolean;\n}\n\nexport interface SkillSourceInstallResultPayload extends SkillInstallResultPayload {\n source: string;\n kind: HubPullResult['kind'];\n contentHash: string;\n}\n\nexport interface ExtensionMarketplacePackageDetailPayload extends MarketplacePackageDetail {\n installability: {\n available: boolean;\n reason?: string;\n sha256?: string;\n };\n manifest?: Record<string, unknown>;\n packageSummary?: {\n dependencyCount: number;\n lifecycleScripts: string[];\n };\n}\n\nexport class GatewayMarketplaceService {\n private readonly opts: GatewayMarketplaceServiceOptions;\n\n constructor(opts: GatewayMarketplaceServiceOptions) {\n this.opts = opts;\n }\n\n private resolveInstallTarget(target: unknown): {\n target: SkillInstallTarget;\n rootDir?: string;\n lockPath?: string;\n } {\n const normalized = normalizeSkillInstallTarget(target);\n if (normalized === 'global') {\n return { target: normalized };\n }\n const workspace = this.opts.getWorkspacePath();\n return {\n target: normalized,\n rootDir: resolveWorkspaceSkillsDir(workspace),\n lockPath: resolveWorkspaceSkillsLockPath(workspace),\n };\n }\n\n // ── Local skills (managed dir) ────────────────────────────────────────\n\n getSkillsApi(): {\n catalog: SkillCatalogEntry[];\n managed: ManagedSkillListItem[];\n } & SkillCatalogRuntimeMeta {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n return {\n catalog: snapshot.catalog,\n managed: listManagedSkillDirs(),\n version: snapshot.version,\n loadedAt: snapshot.loadedAt,\n diagnostics: snapshot.diagnostics,\n status: snapshot.status,\n };\n }\n\n getSkillsStatusApi(): SkillCatalogRuntimeMeta {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n return {\n version: snapshot.version,\n loadedAt: snapshot.loadedAt,\n diagnostics: snapshot.diagnostics,\n status: snapshot.status,\n };\n }\n\n getAgentSkillsApi(agentId: string): AgentSkillAvailabilityPayload {\n return this.opts.getAgentService().getAgentSkillAvailability(agentId);\n }\n\n getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null {\n return this.opts.getAgentService().getSkillMarkdownSource(skillName);\n }\n\n deleteSkill(skillId: string, target?: SkillInstallTarget): void {\n const requestedTarget = target ? this.resolveInstallTarget(target) : undefined;\n const workspaceTarget = requestedTarget ?? this.resolveInstallTarget('workspace');\n try {\n removeSkillsLockEntry(skillId, workspaceTarget.lockPath);\n deleteManagedSkillDir(skillId, workspaceTarget.rootDir);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n return;\n } catch (err) {\n if (requestedTarget || !(err instanceof Error) || !err.message.includes('Skill not found')) {\n throw err;\n }\n }\n\n removeSkillsLockEntry(skillId);\n deleteManagedSkillDir(skillId);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n }\n\n installSkillZip(\n buffer: Buffer,\n opts: { skillId?: string; overwrite?: boolean; target?: SkillInstallTarget },\n ): SkillInstallResultPayload {\n const target = this.resolveInstallTarget(opts.target);\n const result = installSkillFromZip(buffer, {\n skillId: opts.skillId,\n overwrite: opts.overwrite,\n rootDir: target.rootDir,\n });\n removeSkillsLockEntry(result.skillId, target.lockPath);\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n return {\n ...result,\n target: target.target,\n availability: this.getInstallAvailability(result.skillId),\n };\n }\n\n reloadSkills(): void {\n this.opts.getAgentService().refreshSkillsAfterDiskChange();\n }\n\n patchSkillEnabled(skillName: string, enabled: boolean): void {\n createSkillConfigManager(resolveStateDir()).setSkillEnabled(skillName, enabled);\n this.opts.getAgentService().refreshSkillsAfterSkillConfigChange();\n }\n\n // ── Skills marketplace catalog ────────────────────────────────────────\n\n async fetchSkillsCatalog(\n params: SkillsStoreListParams,\n provider?: string,\n ): Promise<UnifiedMarketplaceListResponse> {\n const { listMarketplacePackages } = await import('../../agent/skills/skills-marketplace.js');\n return listMarketplacePackages(this.opts.getConfig(), params, provider);\n }\n\n async fetchSkillsCategories(\n provider?: string,\n ): Promise<{ items: MarketplaceCategoryOption[] }> {\n const { listMarketplaceCategories } = await import('../../agent/skills/skills-marketplace.js');\n return listMarketplaceCategories(this.opts.getConfig(), provider);\n }\n\n async fetchSkillsPackageDetail(\n packageName: string,\n provider?: string,\n ): Promise<UnifiedMarketplacePackageDetail> {\n const { getMarketplacePackageDetail } = await import('../../agent/skills/skills-marketplace.js');\n return getMarketplacePackageDetail(this.opts.getConfig(), packageName, provider);\n }\n\n async installSkill(opts: {\n name: string;\n version?: string;\n overwrite?: boolean;\n provider?: string;\n target?: SkillInstallTarget;\n }): Promise<SkillInstallResultPayload> {\n const { downloadFromMarketplace } = await import('../../agent/skills/skills-marketplace.js');\n const { buffer, skillId } = await downloadFromMarketplace(\n this.opts.getConfig(),\n opts.name,\n opts.version,\n opts.provider,\n );\n return this.installSkillZip(buffer, {\n skillId,\n overwrite: opts.overwrite ?? false,\n target: opts.target,\n });\n }\n\n async installSkillFromSource(\n opts: SkillSourceInstallOptions,\n ): Promise<SkillSourceInstallResultPayload> {\n const result = await this.opts.getAgentService().installSkillFromSource({\n source: opts.source,\n ref: opts.ref,\n path: opts.path,\n skillId: opts.skillId,\n target: opts.target,\n workspace: this.opts.getWorkspacePath(),\n force: opts.force ?? false,\n strictScan: opts.strictScan ?? false,\n });\n return {\n skillId: result.skillId,\n path: result.path,\n target: result.target,\n source: result.source,\n kind: result.kind,\n contentHash: result.contentHash,\n availability: this.getInstallAvailability(result.skillId),\n };\n }\n\n async getSkillsProvider(): Promise<{ provider: string; displayName: string }> {\n const {\n getMarketplaceProviderDisplayName,\n resolveSkillsMarketplaceProvider,\n } = await import('../../agent/skills/skills-marketplace.js');\n const provider = resolveSkillsMarketplaceProvider(this.opts.getConfig());\n return {\n provider,\n displayName: getMarketplaceProviderDisplayName(provider),\n };\n }\n\n /** All registered marketplace providers (built-in + extension-contributed). */\n async getSkillsProviders(): Promise<Array<{ id: string; displayName: string }>> {\n const { listRegisteredProviders } = await import('../../agent/skills/skills-marketplace.js');\n return listRegisteredProviders();\n }\n\n private getDefaultAgentId(): string {\n return this.opts.getConfig().agents?.default || 'main';\n }\n\n private getInstallAvailability(skillId: string): SkillInstallAvailability {\n const snapshot = this.opts.getAgentService().getSkillCatalogSnapshot();\n const catalogEntry =\n snapshot.catalog.find((s) => s.directoryId === skillId) ??\n snapshot.catalog.find((s) => s.name === skillId);\n const defaultAgentId = this.getDefaultAgentId();\n const agentSkills = this.getAgentSkillsApi(defaultAgentId);\n const agentEntry = catalogEntry\n ? agentSkills.skills.find((s) => s.name === catalogEntry.name)\n : undefined;\n const relevantDiagnostics = snapshot.diagnostics.filter((diag) => {\n if (!catalogEntry) return diag.path?.includes(skillId) || diag.skillName === skillId;\n return diag.skillName === catalogEntry.name || diag.path?.startsWith(catalogEntry.path);\n });\n return {\n skillId,\n ...(catalogEntry ? { skillName: catalogEntry.name } : {}),\n loaded: Boolean(catalogEntry),\n ...(catalogEntry ? { enabled: catalogEntry.enabled } : {}),\n defaultAgentId,\n ...(agentEntry ? { availableForDefaultAgent: agentEntry.availableForCurrentAgent } : {}),\n ...(agentEntry?.unavailableReason ? { unavailableReason: agentEntry.unavailableReason } : {}),\n diagnostics: relevantDiagnostics,\n };\n }\n\n // ── Extension marketplace ─────────────────────────────────────────────\n\n /** xopc-store extension package preview (type must be `extension`). */\n async fetchExtensionPackageDetail(\n packageName: string,\n ): Promise<ExtensionMarketplacePackageDetailPayload> {\n const {\n downloadExtensionStoreZipBuffer,\n fetchMarketplacePackageDetail,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n verifyStoreArtifactSha256,\n } = await import('../../agent/skills/marketplace/adapters/store/store-api-client.js');\n const base = resolveExtensionsStoreBaseUrl(this.opts.getConfig());\n const detail = await fetchMarketplacePackageDetail(base, packageName.trim());\n if (detail.type !== 'extension') {\n throw new Error(\n `Package \"${packageName}\" is not an extension (store type: ${detail.type}).`,\n );\n }\n\n try {\n const resolved = await resolveExtensionZipDownloadUrl(base, packageName.trim());\n const buffer = await downloadExtensionStoreZipBuffer(base, resolved.downloadUrl);\n verifyStoreArtifactSha256(buffer, resolved.sha256);\n const {\n peekExtensionManifestFromStoreZip,\n peekExtensionPackageJsonFromStoreZip,\n } = await import('../../extensions/install.js');\n const manifest = peekExtensionManifestFromStoreZip(buffer);\n const packageJson = peekExtensionPackageJsonFromStoreZip(buffer);\n const dependencies = packageJson?.dependencies;\n const dependencyCount = dependencies && typeof dependencies === 'object' && !Array.isArray(dependencies)\n ? Object.keys(dependencies).length\n : 0;\n const scripts = packageJson?.scripts;\n const lifecycleNames = new Set(['preinstall', 'install', 'postinstall', 'prepare']);\n const lifecycleScripts = scripts && typeof scripts === 'object' && !Array.isArray(scripts)\n ? Object.keys(scripts).filter((name) => lifecycleNames.has(name))\n : [];\n\n return {\n ...detail,\n installability: { available: true, sha256: resolved.sha256 },\n ...(manifest ? { manifest } : {}),\n packageSummary: { dependencyCount, lifecycleScripts },\n };\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n return {\n ...detail,\n installability: { available: false, reason },\n };\n }\n }\n\n /**\n * Install an extension from xopc-store into `~/.xopc/extensions`, append id\n * to `extensions.enabled`, refresh the loader, and emit `config.reload`.\n * Returns `requiresGatewayRestart=true` when a new channel plugin would have\n * to wire into the running gateway (channel registration cannot hot-patch).\n */\n async installExtension(opts: {\n name: string;\n version?: string;\n overwrite?: boolean;\n }): Promise<{ extensionId: string; version: string; requiresGatewayRestart: boolean }> {\n const packageName = opts.name.trim();\n if (!packageName) {\n throw new Error('Package name is required');\n }\n const cfg = this.opts.getConfig();\n const {\n downloadExtensionStoreZipBuffer,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n verifyStoreArtifactSha256,\n } = await import('../../agent/skills/marketplace/adapters/store/store-api-client.js');\n const {\n commitStagedExtensionInstall,\n finalizeStagedExtensionInstall,\n rollbackStagedExtensionInstall,\n stageExtensionStoreZip,\n } = await import('../../extensions/install-transaction.js');\n const storeBase = resolveExtensionsStoreBaseUrl(cfg);\n const targetDir = resolveExtensionsDir();\n\n const { downloadUrl, version, sha256 } = await resolveExtensionZipDownloadUrl(\n storeBase,\n packageName,\n opts.version,\n );\n const buf = await downloadExtensionStoreZipBuffer(storeBase, downloadUrl);\n verifyStoreArtifactSha256(buf, sha256);\n\n const transaction = await stageExtensionStoreZip(buf, targetDir);\n const lock = getExtensionLockfileManager();\n const lockSnapshot = await lock.load();\n let configSaved = false;\n let lockWriteStarted = false;\n try {\n commitStagedExtensionInstall(transaction, opts.overwrite ?? false);\n\n const nextConfig = this.mergeExtensionEnabledIntoConfig(cfg, transaction.extensionId);\n const saved = await this.opts.saveConfig(nextConfig);\n if (!saved.saved) {\n throw new Error(saved.error ?? 'Failed to save config after extension install');\n }\n configSaved = true;\n\n lockWriteStarted = true;\n await lock.upsert(transaction.extensionId, {\n name: transaction.extensionId,\n version,\n resolved: packageName,\n artifactUrl: downloadUrl,\n source: 'store',\n });\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n const rollbackErrors: string[] = [];\n\n try {\n rollbackStagedExtensionInstall(transaction);\n } catch (rollbackErr) {\n rollbackErrors.push(`files: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);\n }\n if (configSaved) {\n try {\n const restored = await this.opts.saveConfig(cfg);\n if (!restored.saved) {\n rollbackErrors.push(`config: ${restored.error ?? 'restore failed'}`);\n }\n } catch (rollbackErr) {\n rollbackErrors.push(`config: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);\n }\n }\n if (lockWriteStarted) {\n try {\n await lock.save(lockSnapshot);\n } catch (rollbackErr) {\n rollbackErrors.push(`lockfile: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);\n }\n }\n\n const rollbackSuffix = rollbackErrors.length > 0\n ? ` Rollback incomplete (${rollbackErrors.join('; ')}).`\n : '';\n log.error(\n { err, errorMessage: em, extensionId: transaction.extensionId, rollbackErrors },\n `Marketplace extension install failed: ${em}${rollbackSuffix}`,\n );\n throw new Error(`${em}${rollbackSuffix}`, { cause: err });\n }\n\n try {\n finalizeStagedExtensionInstall(transaction);\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn(\n { err, errorMessage: em, extensionId: transaction.extensionId },\n `Installed extension but temporary backup cleanup failed: ${em}`,\n );\n }\n\n this.opts.getExtensionLoader()?.invalidateManifestCache();\n this.opts.emit('config.reload', { section: 'extensions', source: 'marketplace-install' });\n return { extensionId: transaction.extensionId, version, requiresGatewayRestart: true };\n }\n\n /** Remove a user-installed extension (global or per-agent dir) from disk and config. */\n async uninstallExtension(extensionId: string): Promise<{ requiresGatewayRestart: boolean }> {\n const id = extensionId.trim();\n if (!id) {\n throw new Error('extensionId is required');\n }\n const loader = this.opts.getExtensionLoader();\n if (!loader) {\n throw new Error('Extensions unavailable');\n }\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === id);\n if (!ext) {\n throw new Error(`Extension not found: ${id}`);\n }\n if (ext.source === 'bundled') {\n throw new Error('Built-in extensions cannot be uninstalled from the marketplace UI');\n }\n if (existsSync(ext.path)) {\n rmSync(ext.path, { recursive: true, force: true });\n }\n await getExtensionLockfileManager().remove(id);\n\n const nextConfig = this.mergeExtensionRemovedFromEnabledConfig(this.opts.getConfig(), id);\n const saved = await this.opts.saveConfig(nextConfig);\n if (!saved.saved) {\n throw new Error(saved.error ?? 'Failed to save config after extension uninstall');\n }\n try {\n loader.invalidateManifestCache();\n await loader.loadByActivationPlan();\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Extension loader refresh after uninstall failed: ${em}`);\n }\n this.opts.emit('config.reload', { section: 'extensions', source: 'marketplace-uninstall' });\n return { requiresGatewayRestart: true };\n }\n\n // ── Internals ─────────────────────────────────────────────────────────\n\n private mergeExtensionEnabledIntoConfig(currentConfig: Config, extensionId: string): Config {\n const id = extensionId.trim();\n const prevExt = currentConfig.extensions;\n const baseExt =\n prevExt && typeof prevExt === 'object' && !Array.isArray(prevExt)\n ? { ...(prevExt as Record<string, unknown>) }\n : {};\n const enabledRaw = baseExt.enabled;\n const enabled = Array.isArray(enabledRaw)\n ? [...enabledRaw.filter((x): x is string => typeof x === 'string')]\n : [];\n if (!enabled.includes(id)) enabled.push(id);\n\n const disabledRaw = baseExt.disabled;\n const nextExt: Record<string, unknown> = { ...baseExt, enabled };\n if (Array.isArray(disabledRaw)) {\n const next = disabledRaw.filter((x): x is string => typeof x === 'string' && x !== id);\n if (next.length > 0) nextExt.disabled = next;\n else delete nextExt.disabled;\n }\n\n return {\n ...currentConfig,\n extensions: nextExt,\n } as Config;\n }\n\n private mergeExtensionRemovedFromEnabledConfig(currentConfig: Config, extensionId: string): Config {\n const id = extensionId.trim();\n const prevExt = currentConfig.extensions;\n const baseExt =\n prevExt && typeof prevExt === 'object' && !Array.isArray(prevExt)\n ? { ...(prevExt as Record<string, unknown>) }\n : {};\n const enabledRaw = baseExt.enabled;\n const enabled = Array.isArray(enabledRaw)\n ? enabledRaw.filter((x): x is string => typeof x === 'string' && x !== id)\n : [];\n return {\n ...currentConfig,\n extensions: { ...baseExt, enabled },\n } as Config;\n }\n}\n"],"mappings":"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"}
|
|
@@ -81,6 +81,8 @@ export declare class GatewayService {
|
|
|
81
81
|
constructor(serviceConfig?: GatewayServiceConfig);
|
|
82
82
|
/** Lazy AgentService — constructed on first use or during `start()`. */
|
|
83
83
|
get agentService(): AgentService;
|
|
84
|
+
refreshActionTrustPolicy(): void;
|
|
85
|
+
refreshUserProfileContext(): void;
|
|
84
86
|
private ensureAgentService;
|
|
85
87
|
private ensureHeartbeatService;
|
|
86
88
|
private createGoalRunner;
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { __toCommonJS } from "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
|
|
3
|
-
import { getLogDir } from "../utils/logger/config.js";
|
|
4
|
-
import { getRuntimeLogStats } from "../utils/logger/stats.js";
|
|
5
|
-
import { createLogger } from "../utils/logger/index.js";
|
|
6
|
-
import { init_logger } from "../utils/logger.js";
|
|
7
|
-
import { closeXopcDatabase, openXopcDatabase } from "../storage/sqlite/connection.js";
|
|
8
|
-
import "../storage/sqlite/index.js";
|
|
9
3
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
10
4
|
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveDefaultAgentId } from "../agent/agent-scope.js";
|
|
11
5
|
import { buildSessionKey, init_session_key, sanitizeSegment } from "../routing/session-key.js";
|
|
12
6
|
import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
7
|
+
import { getLogDir } from "../utils/logger/config.js";
|
|
8
|
+
import { getRuntimeLogStats } from "../utils/logger/stats.js";
|
|
9
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
10
|
+
import { init_logger } from "../utils/logger.js";
|
|
13
11
|
import { init_paths, resolveAgentDir, resolveConfigPath, resolveExtensionsDir } from "../config/paths.js";
|
|
14
12
|
import { areExtensionsGloballyDisabled } from "../extensions/discover-extensions.js";
|
|
15
13
|
import { buildExtensionMetadataSnapshot } from "../extensions/extension-metadata-snapshot.js";
|
|
@@ -18,15 +16,17 @@ import { loadConfig, saveConfig } from "../config/loader.js";
|
|
|
18
16
|
import { prewarmModelRegistry } from "../providers/model-registry.js";
|
|
19
17
|
import { init_providers, providers_exports } from "../providers/index.js";
|
|
20
18
|
import { onAutomationProductEvent, publishAutomationProductEvent } from "../automations/product-events.js";
|
|
19
|
+
import { closeXopcDatabase, openXopcDatabase } from "../storage/sqlite/connection.js";
|
|
21
20
|
import { GoalRunner } from "../goals/goal-runner.js";
|
|
22
21
|
import { GoalNotificationService } from "../goals/goal-notifications.js";
|
|
23
22
|
import "../goals/index.js";
|
|
23
|
+
import "../storage/sqlite/index.js";
|
|
24
24
|
import { resolveEffectiveGatewayPort } from "./host.js";
|
|
25
|
-
import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
|
|
26
25
|
import { ProjectService } from "../projects/project-service.js";
|
|
27
26
|
import "../projects/index.js";
|
|
28
27
|
import { disposeAllSessionMcpRuntimes } from "../agent/mcp/bundle-mcp-runtime.js";
|
|
29
28
|
import "../agent/mcp/bundle-mcp-tools.js";
|
|
29
|
+
import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
|
|
30
30
|
import { SessionIndex } from "../session/manager.js";
|
|
31
31
|
import "../session/index.js";
|
|
32
32
|
import { ExtensionLoader } from "../extensions/loader.js";
|
|
@@ -267,6 +267,12 @@ var GatewayService = class {
|
|
|
267
267
|
get agentService() {
|
|
268
268
|
return this.ensureAgentService();
|
|
269
269
|
}
|
|
270
|
+
refreshActionTrustPolicy() {
|
|
271
|
+
this._agentService?.refreshActionTrustPolicy();
|
|
272
|
+
}
|
|
273
|
+
refreshUserProfileContext() {
|
|
274
|
+
this._agentService?.refreshUserProfileContext();
|
|
275
|
+
}
|
|
270
276
|
ensureAgentService() {
|
|
271
277
|
if (this._agentService) return this._agentService;
|
|
272
278
|
this._agentService = new AgentService(this.bus, {
|