@xopcai/xopc 0.0.127 → 0.0.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CgGgO4OV.js → agent-avatar-dicebear-DHzfg5D-.js} +1 -1
- package/dist/gateway/static/root/assets/agents-CMxKKFQD.js +2 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-ptk9c5BN.js +1 -0
- package/dist/gateway/static/root/assets/{appearance-settings-BnHQW7Hv.js → appearance-settings-bYeEj3IW.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DdZvDf5B.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-5NXT7Zqv.js → archive-plugin-Dy6lsTHw.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DghwhYe0.js → attachment-load-qOtBYR6Y.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-DYmESgwl.js → automation-suggestion-card-BFH-RfaV.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-B8JTjkCr.js +4 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DSbPKdWX.js → binary-plugins-DJvi_thc.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CoZ-_np-.js → block-editor-DlMnizlt.js} +4 -4
- package/dist/gateway/static/root/assets/browser-settings-page-slHLiZgi.js +8 -0
- package/dist/gateway/static/root/assets/capability-presets-api-D4q7vHVJ.js +1 -0
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Dng8Grpv.js +1 -0
- package/dist/gateway/static/root/assets/channel-recipient-api-BrW5Kcgc.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-KIsISXw0.js +1 -0
- package/dist/gateway/static/root/assets/{code-editor-gbRgS14t.js → code-editor--tMO38Tr.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-C5fx4Qs9.js +2 -0
- package/dist/gateway/static/root/assets/desktop-pet-Jmdn6q47.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-settings-npJ0Oh5p.js → desktop-pet-settings-B-u63N4e.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BR2ItBuf.js → directory-picker-path-field-8p1ehIHn.js} +1 -1
- package/dist/gateway/static/root/assets/dreaming-settings-CCkKP-I4.js +3 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Tl0f1rNv.js → extension-debug-page-DJ1ABK95.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Ck7QuwE3.js → extension-page-CP9P2lGM.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-DnhU-tx0.js +1 -0
- package/dist/gateway/static/root/assets/fetch-BMjlW0g1.js +1 -0
- package/dist/gateway/static/root/assets/gateway-config-api-CjxDn46s.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-TING7224.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-Yh8h3hkj.js → gateway-startup-retry-CY5W2Pp4.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-2lPbGfp3.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-DHWVRafk.js +4 -0
- package/dist/gateway/static/root/assets/goals-config-api-BqhuxG8P.js +1 -0
- package/dist/gateway/static/root/assets/goals-page-CMk-9ZYN.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-BHzOAU_l.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-BQIm0P3V.js +1 -0
- package/dist/gateway/static/root/assets/{html-workspace-editor-DV90ddkE.js → html-workspace-editor-COqmtESs.js} +1 -1
- package/dist/gateway/static/root/assets/index-C4k6QSXw.js +257 -0
- package/dist/gateway/static/root/assets/index-EKmpPvZj.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CfQrt_Rb.js → keyboard-shortcuts-settings-BrENZzM7.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-BiL302Ve.js +2 -0
- package/dist/gateway/static/root/assets/{markdown-editor-BFOjBBla.js → markdown-editor-jD1LPiP-.js} +2 -2
- package/dist/gateway/static/root/assets/{markdown-split-BwiMdCf_.js → markdown-split-BYF4ReGM.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DhoizyZv.js → media-plugins-CpQDz-QJ.js} +1 -1
- package/dist/gateway/static/root/assets/messages-YzjnURPJ.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-CFPpl3Cq.js +2 -0
- package/dist/gateway/static/root/assets/notes-page-BurgcdVZ.js +1 -0
- package/dist/gateway/static/root/assets/notes-workbench-BAELRM_O.js +2 -0
- package/dist/gateway/static/root/assets/{page-tabs-DDC2t4Z8.js → page-tabs-RnYYOIWO.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BTmk-XDM.js → preview-open-alternatives-CTRt06Ri.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-iXX1Ceo2.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-GDVTFAY7.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BUrbUnwv.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-DqU-yKIh.js → save-bar-controls-c4pZeikq.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-CUttkoSB.js → schedule-field-Cb6R7iuP.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-CVSQA9nI.js → schema-form-BqET_hEP.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CiOreA2k.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-C-qvptlu.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-CK7ogS-P.js → settings-collapsible-section-DuOvqNsI.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-Bugp38Fa.js → settings-form-section-DptSsbWd.js} +1 -1
- package/dist/gateway/static/root/assets/settings-loading-skeleton-BlVfBCb9.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-DBRWwdhh.js → settings-page-layout-DVt69dJJ.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-xQx2Pkg5.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-DWB8VdLK.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-8m_ACH0z.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-CgxfhNxI.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BBFUOxmf.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-bo695odu.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-DJ6YuLqR.js → system-settings-panel-CW22OkZ4.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-B0T7N8Km.js → typed-models-lib-BqpGAKxV.js} +1 -1
- package/dist/gateway/static/root/assets/url-DFGNSBNT.js +1 -0
- package/dist/gateway/static/root/assets/use-channel-catalog-CPdJ0o0i.js +1 -0
- package/dist/gateway/static/root/assets/user-profile-settings-panel-CERVLuaW.js +1 -0
- package/dist/gateway/static/root/assets/{utils-CehXcWAY.js → utils-BnmysurA.js} +1 -1
- package/dist/gateway/static/root/assets/vendor-codemirror-C1WKjCk5.js +45 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-Jr3jvPcB.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-B-8rex4u.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-c4jeaohQ.js → workflow-run-setup-panel-Ci9GSPnS.js} +2 -2
- package/dist/gateway/static/root/assets/{workflow-start-dialog-ENRHjoqa.js → workflow-start-dialog-BhDj8pqH.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-Brb3UGvs.js +18 -0
- package/dist/gateway/static/root/index.html +7 -6
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +3 -0
- package/dist/src/agent/agent-manager.js +14 -6
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/capabilities/definitions.d.ts +14 -0
- package/dist/src/agent/capabilities/definitions.js +19 -0
- package/dist/src/agent/capabilities/definitions.js.map +1 -1
- package/dist/src/agent/goals/post-turn.js +23 -2
- package/dist/src/agent/goals/post-turn.js.map +1 -1
- package/dist/src/agent/messaging/command-handler.d.ts +4 -0
- package/dist/src/agent/messaging/command-handler.js +6 -0
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/service.d.ts +2 -0
- package/dist/src/agent/service.js +23 -0
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/skills/hub-lock.d.ts +5 -5
- package/dist/src/agent/skills/hub-lock.js +12 -12
- package/dist/src/agent/skills/hub-lock.js.map +1 -1
- package/dist/src/agent/skills/hub-pull.d.ts +15 -0
- package/dist/src/agent/skills/hub-pull.js +299 -24
- package/dist/src/agent/skills/hub-pull.js.map +1 -1
- package/dist/src/agent/skills/index.js +4 -40
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/install-target.d.ts +3 -0
- package/dist/src/agent/skills/install-target.js +11 -0
- package/dist/src/agent/skills/install-target.js.map +1 -0
- package/dist/src/agent/skills/managed-store.d.ts +5 -3
- package/dist/src/agent/skills/managed-store.js +10 -9
- package/dist/src/agent/skills/managed-store.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +5 -3
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +21 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +62 -6
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
- package/dist/src/agent/skills/marketplace/resolve-adapter.js +1 -1
- package/dist/src/agent/skills/marketplace/resolve-adapter.js.map +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +2 -2
- package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -6
- package/dist/src/agent/skills/skill-manager.js.map +1 -1
- package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
- package/dist/src/agent/skills/workspace-skills-dir.js +5 -1
- package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -1
- package/dist/src/agent/tools/automation-tool.d.ts +6 -6
- package/dist/src/agent/tools/browser/tool/schemas.d.ts +20 -20
- package/dist/src/agent/tools/composio-tool.d.ts +3 -3
- package/dist/src/agent/tools/desktop-pet-tool.d.ts +7 -7
- package/dist/src/agent/tools/factory.d.ts +3 -0
- package/dist/src/agent/tools/factory.js +6 -1
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/goal-tool.d.ts +16 -16
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/skill-install-tool.d.ts +28 -0
- package/dist/src/agent/tools/skill-install-tool.js +81 -0
- package/dist/src/agent/tools/skill-install-tool.js.map +1 -0
- package/dist/src/agent/tools/skill-manage-tool.js +3 -6
- package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
- package/dist/src/agent/tools/tool-manual-tool.d.ts +2 -2
- package/dist/src/agent/tools/xopc-use-tool.d.ts +5 -5
- package/dist/src/automations/domain/types.d.ts +1 -0
- package/dist/src/automations/draft/automation-draft-service.js +1 -1
- package/dist/src/automations/service/automation-service.js +9 -0
- package/dist/src/automations/service/automation-service.js.map +1 -1
- package/dist/src/browser/schemas.d.ts +52 -52
- package/dist/src/capabilities/store-connector.d.ts +17 -0
- package/dist/src/capabilities/store-connector.js +191 -0
- package/dist/src/capabilities/store-connector.js.map +1 -0
- package/dist/src/chat-commands/builtins/skill.d.ts +1 -0
- package/dist/src/chat-commands/builtins/skill.js +132 -0
- package/dist/src/chat-commands/builtins/skill.js.map +1 -0
- package/dist/src/chat-commands/context.d.ts +3 -0
- package/dist/src/chat-commands/context.js +2 -0
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/chat-commands/index.d.ts +1 -0
- package/dist/src/chat-commands/index.js +3 -1
- package/dist/src/chat-commands/index.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +17 -0
- package/dist/src/cli/command-loaders.js +1 -0
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +4 -0
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agent.js +2 -2
- package/dist/src/cli/commands/connectors.d.ts +4 -0
- package/dist/src/cli/commands/connectors.js +96 -0
- package/dist/src/cli/commands/connectors.js.map +1 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/profile.js +1 -1
- package/dist/src/cli/commands/skills.js +1 -1
- package/dist/src/cli/commands/tunnel.js +1 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/cli/extension-cli-register.js +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/index.js +1 -1
- package/dist/src/config/schema.js +2 -2
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/connectors/install.js +3 -1
- package/dist/src/connectors/install.js.map +1 -1
- package/dist/src/connectors/materialize.js +2 -0
- package/dist/src/connectors/materialize.js.map +1 -1
- package/dist/src/connectors/types.d.ts +19 -1
- package/dist/src/extensions/install.js +1 -1
- package/dist/src/extensions/types/manifest.d.ts +1 -1
- package/dist/src/extensions/update.js +5 -3
- package/dist/src/extensions/update.js.map +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +5 -1
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +2 -0
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/middleware/auth.d.ts +2 -2
- package/dist/src/gateway/hono/middleware/logger.d.ts +1 -1
- package/dist/src/gateway/hono/middleware/route-errors.d.ts +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +2 -2
- package/dist/src/gateway/hono/routes/capabilities.d.ts +3 -0
- package/dist/src/gateway/hono/routes/capabilities.js +79 -0
- package/dist/src/gateway/hono/routes/capabilities.js.map +1 -0
- package/dist/src/gateway/hono/routes/commands-skills.js +81 -3
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +2 -2
- package/dist/src/gateway/hono/routes/goals.js +212 -3
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/gateway/hono/routes/index.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/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/mobile.d.ts +3 -0
- package/dist/src/gateway/hono/routes/mobile.js +113 -0
- package/dist/src/gateway/hono/routes/mobile.js.map +1 -0
- package/dist/src/gateway/hono/routes/projects.js +17 -0
- package/dist/src/gateway/hono/routes/projects.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +4 -1
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.d.ts +3 -3
- package/dist/src/gateway/run-loop.js +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +23 -1
- package/dist/src/gateway/service/marketplace-service.js +57 -6
- 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 +12 -2
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/goals/goal-contract-draft.d.ts +15 -0
- package/dist/src/goals/goal-contract-draft.js +114 -0
- package/dist/src/goals/goal-contract-draft.js.map +1 -0
- package/dist/src/goals/goal-evidence-review.d.ts +15 -0
- package/dist/src/goals/goal-evidence-review.js +91 -0
- package/dist/src/goals/goal-evidence-review.js.map +1 -0
- package/dist/src/goals/goal-runner.js +3 -1
- package/dist/src/goals/goal-runner.js.map +1 -1
- package/dist/src/goals/goal-service.d.ts +17 -1
- package/dist/src/goals/goal-service.js +44 -3
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/goals/goal-store.d.ts +18 -1
- package/dist/src/goals/goal-store.js +190 -1
- package/dist/src/goals/goal-store.js.map +1 -1
- package/dist/src/goals/index.d.ts +4 -0
- package/dist/src/goals/index.js +3 -1
- package/dist/src/goals/types.d.ts +42 -0
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/mobile/notification-service.d.ts +8 -0
- package/dist/src/mobile/notification-service.js +139 -0
- package/dist/src/mobile/notification-service.js.map +1 -0
- package/dist/src/mobile/notification-store.d.ts +28 -0
- package/dist/src/mobile/notification-store.js +134 -0
- package/dist/src/mobile/notification-store.js.map +1 -0
- package/dist/src/mobile/notification-types.d.ts +37 -0
- package/dist/src/mobile/notification-types.js +11 -0
- package/dist/src/mobile/notification-types.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/026_goal_contracts.sql +10 -0
- package/dist/src/storage/sqlite/migrations/027_mobile_notifications.sql +43 -0
- package/dist/src/storage/sqlite/migrations/028_goal_evidence_requirements.sql +47 -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/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +44 -0
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/package.json +1 -1
- package/skills/THIRD_PARTY_NOTICES.md +16 -0
- package/skills/creative/algorithmic-art/SKILL.md +37 -0
- package/skills/creative/algorithmic-art/templates/generator-template.js +27 -0
- package/skills/creative/algorithmic-art/templates/viewer.html +27 -0
- package/skills/documents/doc-coauthoring/SKILL.md +40 -0
- package/skills/documents/doc-coauthoring/references/reader-review.md +9 -0
- package/skills/documents/docx/SKILL.md +40 -0
- package/skills/documents/docx/references/editing-checklist.md +8 -0
- package/skills/documents/docx/scripts/inspect_ooxml.py +36 -0
- package/skills/documents/docx/scripts/render_docx.py +33 -0
- package/skills/documents/pdf/SKILL.md +47 -0
- package/skills/documents/pdf/references/operations.md +16 -0
- package/skills/documents/pdf/scripts/inspect_pdf.py +41 -0
- package/skills/documents/pdf/scripts/render_pdf.py +32 -0
- package/skills/documents/pptx/SKILL.md +41 -0
- package/skills/documents/pptx/references/qa-checklist.md +6 -0
- package/skills/documents/pptx/scripts/inspect_ooxml.py +34 -0
- package/skills/documents/pptx/scripts/render_pptx.py +33 -0
- package/skills/engineering/define-goal/SKILL.md +41 -0
- package/skills/engineering/define-goal/references/objective-rubric.md +12 -0
- package/dist/gateway/static/root/assets/agents-k59l7NMb.js +0 -2
- package/dist/gateway/static/root/assets/app-management-settings-panel-DeQsTsyy.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-BG9b4abG.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-De8mVutL.js +0 -4
- package/dist/gateway/static/root/assets/browser-settings-page-C_ZRa4LF.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-api-hny224j-.js +0 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Drc0qLsw.js +0 -1
- package/dist/gateway/static/root/assets/channel-recipient-api-DAlOHxKJ.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-CA20zBV9.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-qMyMB5te.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-XG6Vb_fZ.js +0 -1
- package/dist/gateway/static/root/assets/dreaming-settings-CkUZ997f.js +0 -3
- package/dist/gateway/static/root/assets/extension-settings-page-3RMhQtZ3.js +0 -1
- package/dist/gateway/static/root/assets/fetch-pg2ErdAk.js +0 -1
- package/dist/gateway/static/root/assets/gateway-config-api-DbG97ia2.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-B8cyqKk-.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-DmeW7Zz3.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-DrTyGbVD.js +0 -1
- package/dist/gateway/static/root/assets/goals-config-api-CxCWGIBB.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-DV1bJhIh.js +0 -2
- package/dist/gateway/static/root/assets/goals-settings-9DrfOkP5.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-KaDpZrv0.js +0 -1
- package/dist/gateway/static/root/assets/index-C2F0Clvm.js +0 -256
- package/dist/gateway/static/root/assets/index-COQSX5d_.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-C9dpiNTF.js +0 -2
- package/dist/gateway/static/root/assets/messages-DmnbiNxU.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-zdCdmBmH.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-MpGeFfPt.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-DYCM3yd2.js +0 -2
- package/dist/gateway/static/root/assets/project-detail-page-Cu0ElRnS.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DakNaUjZ.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DYKjt7L9.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CcGHDsz1.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CuFdeKNu.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-0AJoUvxi.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-D6a_hEk7.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-BtsuETKF.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-CcEFT7S9.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BcN_RuTD.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-BbRZZZA5.js +0 -2
- package/dist/gateway/static/root/assets/use-channel-catalog-C6vrxdzZ.js +0 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-DZ0nKMgj.js +0 -1
- package/dist/gateway/static/root/assets/vendor-codemirror-BvNgyE1Q.js +0 -45
- package/dist/gateway/static/root/assets/voice-api-key-field-2QKflCx8.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-DfJnuWq1.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-BJwwFTm_.js +0 -18
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { getStoreConnectorInstallPlan, installStoreConnector, listStoreConnectors } from "../../../capabilities/store-connector.js";
|
|
2
|
+
//#region src/gateway/hono/routes/capabilities.ts
|
|
3
|
+
function errorMessage(error) {
|
|
4
|
+
return error instanceof Error ? error.message : String(error);
|
|
5
|
+
}
|
|
6
|
+
function optionalVersion(body) {
|
|
7
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
|
|
8
|
+
const value = body.version;
|
|
9
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
10
|
+
}
|
|
11
|
+
function registerCapabilityRoutes(authenticated, deps) {
|
|
12
|
+
const { service, strictRateLimitMiddleware } = deps;
|
|
13
|
+
authenticated.get("/api/capabilities/connectors", async (c) => {
|
|
14
|
+
try {
|
|
15
|
+
const page = Number(c.req.query("page") ?? "1");
|
|
16
|
+
const pageSize = Number(c.req.query("pageSize") ?? "24");
|
|
17
|
+
const result = await listStoreConnectors(service.currentConfig, {
|
|
18
|
+
q: c.req.query("q"),
|
|
19
|
+
page: Number.isFinite(page) ? Math.max(1, page) : 1,
|
|
20
|
+
pageSize: Number.isFinite(pageSize) ? Math.min(50, Math.max(1, pageSize)) : 24,
|
|
21
|
+
sort: c.req.query("sort") === "newest" ? "newest" : "downloads",
|
|
22
|
+
category: c.req.query("category")
|
|
23
|
+
});
|
|
24
|
+
return c.json({
|
|
25
|
+
ok: true,
|
|
26
|
+
payload: result
|
|
27
|
+
});
|
|
28
|
+
} catch (error) {
|
|
29
|
+
return c.json({
|
|
30
|
+
ok: false,
|
|
31
|
+
error: errorMessage(error)
|
|
32
|
+
}, 502);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
authenticated.post("/api/capabilities/connectors/:name/install-plan", strictRateLimitMiddleware, async (c) => {
|
|
36
|
+
const body = await c.req.json().catch(() => ({}));
|
|
37
|
+
try {
|
|
38
|
+
const plan = await getStoreConnectorInstallPlan(service.currentConfig, c.req.param("name"), optionalVersion(body));
|
|
39
|
+
return c.json({
|
|
40
|
+
ok: true,
|
|
41
|
+
payload: { plan }
|
|
42
|
+
});
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return c.json({
|
|
45
|
+
ok: false,
|
|
46
|
+
error: errorMessage(error)
|
|
47
|
+
}, 400);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
authenticated.post("/api/capabilities/connectors/:name/install", strictRateLimitMiddleware, async (c) => {
|
|
51
|
+
const body = await c.req.json().catch(() => ({}));
|
|
52
|
+
const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
|
|
53
|
+
try {
|
|
54
|
+
const config = service.currentConfig;
|
|
55
|
+
const { instance, plan } = await installStoreConnector(config, c.req.param("name"), input, optionalVersion(body));
|
|
56
|
+
const saved = await service.saveConfig(config);
|
|
57
|
+
if (!saved.saved) return c.json({
|
|
58
|
+
ok: false,
|
|
59
|
+
error: saved.error ?? "Failed to save connector configuration."
|
|
60
|
+
}, 500);
|
|
61
|
+
return c.json({
|
|
62
|
+
ok: true,
|
|
63
|
+
payload: {
|
|
64
|
+
instance,
|
|
65
|
+
plan
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return c.json({
|
|
70
|
+
ok: false,
|
|
71
|
+
error: errorMessage(error)
|
|
72
|
+
}, 400);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { registerCapabilityRoutes };
|
|
78
|
+
|
|
79
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","names":[],"sources":["../../../../../src/gateway/hono/routes/capabilities.ts"],"sourcesContent":["import { Hono } from 'hono';\n\nimport type { Config } from '../../../config/schema.js';\nimport type { ConnectorInstallInput } from '../../../connectors/types.js';\nimport {\n getStoreConnectorInstallPlan,\n installStoreConnector,\n listStoreConnectors,\n} from '../../../capabilities/store-connector.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction optionalVersion(body: unknown): string | undefined {\n if (!body || typeof body !== 'object' || Array.isArray(body)) return undefined;\n const value = (body as Record<string, unknown>).version;\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nexport function registerCapabilityRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n authenticated.get('/api/capabilities/connectors', async (c) => {\n try {\n const page = Number(c.req.query('page') ?? '1');\n const pageSize = Number(c.req.query('pageSize') ?? '24');\n const result = await listStoreConnectors(service.currentConfig as Config, {\n q: c.req.query('q'),\n page: Number.isFinite(page) ? Math.max(1, page) : 1,\n pageSize: Number.isFinite(pageSize) ? Math.min(50, Math.max(1, pageSize)) : 24,\n sort: c.req.query('sort') === 'newest' ? 'newest' : 'downloads',\n category: c.req.query('category'),\n });\n return c.json({ ok: true, payload: result });\n } catch (error) {\n return c.json({ ok: false, error: errorMessage(error) }, 502);\n }\n });\n\n authenticated.post('/api/capabilities/connectors/:name/install-plan', strictRateLimitMiddleware, async (c) => {\n const body = await c.req.json().catch(() => ({}));\n try {\n const plan = await getStoreConnectorInstallPlan(\n service.currentConfig as Config,\n c.req.param('name'),\n optionalVersion(body),\n );\n return c.json({ ok: true, payload: { plan } });\n } catch (error) {\n return c.json({ ok: false, error: errorMessage(error) }, 400);\n }\n });\n\n authenticated.post('/api/capabilities/connectors/:name/install', strictRateLimitMiddleware, async (c) => {\n const body = await c.req.json().catch(() => ({}));\n const input: ConnectorInstallInput = body && typeof body === 'object' && !Array.isArray(body)\n ? body as ConnectorInstallInput\n : {};\n try {\n const config = service.currentConfig as Config;\n const { instance, plan } = await installStoreConnector(\n config,\n c.req.param('name'),\n input,\n optionalVersion(body),\n );\n const saved = await service.saveConfig(config);\n if (!saved.saved) {\n return c.json({ ok: false, error: saved.error ?? 'Failed to save connector configuration.' }, 500);\n }\n return c.json({ ok: true, payload: { instance, plan } });\n } catch (error) {\n return c.json({ ok: false, error: errorMessage(error) }, 400);\n }\n });\n}\n"],"mappings":";;AAWA,SAAS,aAAa,OAAwB;AAC5C,QAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;AAG/D,SAAS,gBAAgB,MAAmC;AAC1D,KAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,KAAK,CAAE,QAAO,KAAA;CACrE,MAAM,QAAS,KAAiC;AAChD,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,KAAA;;AAGpE,SAAgB,yBAAyB,eAAqB,MAAoC;CAChG,MAAM,EAAE,SAAS,8BAA8B;AAE/C,eAAc,IAAI,gCAAgC,OAAO,MAAM;AAC7D,MAAI;GACF,MAAM,OAAO,OAAO,EAAE,IAAI,MAAM,OAAO,IAAI,IAAI;GAC/C,MAAM,WAAW,OAAO,EAAE,IAAI,MAAM,WAAW,IAAI,KAAK;GACxD,MAAM,SAAS,MAAM,oBAAoB,QAAQ,eAAyB;IACxE,GAAG,EAAE,IAAI,MAAM,IAAI;IACnB,MAAM,OAAO,SAAS,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG;IAClD,UAAU,OAAO,SAAS,SAAS,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,SAAS,CAAC,GAAG;IAC5E,MAAM,EAAE,IAAI,MAAM,OAAO,KAAK,WAAW,WAAW;IACpD,UAAU,EAAE,IAAI,MAAM,WAAW;IAClC,CAAC;AACF,UAAO,EAAE,KAAK;IAAE,IAAI;IAAM,SAAS;IAAQ,CAAC;WACrC,OAAO;AACd,UAAO,EAAE,KAAK;IAAE,IAAI;IAAO,OAAO,aAAa,MAAM;IAAE,EAAE,IAAI;;GAE/D;AAEF,eAAc,KAAK,mDAAmD,2BAA2B,OAAO,MAAM;EAC5G,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM,CAAC,aAAa,EAAE,EAAE;AACjD,MAAI;GACF,MAAM,OAAO,MAAM,6BACjB,QAAQ,eACR,EAAE,IAAI,MAAM,OAAO,EACnB,gBAAgB,KAAK,CACtB;AACD,UAAO,EAAE,KAAK;IAAE,IAAI;IAAM,SAAS,EAAE,MAAM;IAAE,CAAC;WACvC,OAAO;AACd,UAAO,EAAE,KAAK;IAAE,IAAI;IAAO,OAAO,aAAa,MAAM;IAAE,EAAE,IAAI;;GAE/D;AAEF,eAAc,KAAK,8CAA8C,2BAA2B,OAAO,MAAM;EACvG,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM,CAAC,aAAa,EAAE,EAAE;EACjD,MAAM,QAA+B,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,KAAK,GACzF,OACA,EAAE;AACN,MAAI;GACF,MAAM,SAAS,QAAQ;GACvB,MAAM,EAAE,UAAU,SAAS,MAAM,sBAC/B,QACA,EAAE,IAAI,MAAM,OAAO,EACnB,OACA,gBAAgB,KAAK,CACtB;GACD,MAAM,QAAQ,MAAM,QAAQ,WAAW,OAAO;AAC9C,OAAI,CAAC,MAAM,MACT,QAAO,EAAE,KAAK;IAAE,IAAI;IAAO,OAAO,MAAM,SAAS;IAA2C,EAAE,IAAI;AAEpG,UAAO,EAAE,KAAK;IAAE,IAAI;IAAM,SAAS;KAAE;KAAU;KAAM;IAAE,CAAC;WACjD,OAAO;AACd,UAAO,EAAE,KAAK;IAAE,IAAI;IAAO,OAAO,aAAa,MAAM;IAAE,EAAE,IAAI;;GAE/D"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { effectiveWorkspacePathForSession } from "../../../session/session-workspace.js";
|
|
2
2
|
import { getProjectForSession } from "../../../projects/workspace.js";
|
|
3
|
+
import { isSkillInstallTarget } from "../../../agent/skills/install-target.js";
|
|
3
4
|
import { commandRegistry } from "../../../chat-commands/registry.js";
|
|
4
5
|
import { isRegisteredProvider } from "../../../agent/skills/marketplace/registry.js";
|
|
5
6
|
import { buildReviewContext, resolveGitRoot } from "../../../review/review-git.js";
|
|
@@ -10,6 +11,23 @@ function parseMarketplaceProviderQuery(raw) {
|
|
|
10
11
|
const v = raw?.trim().toLowerCase();
|
|
11
12
|
if (v && isRegisteredProvider(v)) return v;
|
|
12
13
|
}
|
|
14
|
+
function optionalTrimmedString(value) {
|
|
15
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
16
|
+
}
|
|
17
|
+
function optionalBoolean(value) {
|
|
18
|
+
if (value === true || value === "true" || value === "1") return true;
|
|
19
|
+
if (value === false || value === "false" || value === "0") return false;
|
|
20
|
+
}
|
|
21
|
+
function optionalSkillInstallTarget(value) {
|
|
22
|
+
if (value == null || value === "") return void 0;
|
|
23
|
+
return isSkillInstallTarget(value) ? value : void 0;
|
|
24
|
+
}
|
|
25
|
+
function skillHubInstallStatus(err) {
|
|
26
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
27
|
+
if (message.includes("already exists")) return 409;
|
|
28
|
+
if (message.startsWith("HTTP ") || message.includes("fetching archive") || message.includes("git clone failed") || message.includes("Git operation failed")) return 502;
|
|
29
|
+
return 400;
|
|
30
|
+
}
|
|
13
31
|
function registerCommandsSkillsRoutes(authenticated, deps) {
|
|
14
32
|
const { service } = deps;
|
|
15
33
|
authenticated.get("/api/commands", (c) => {
|
|
@@ -245,6 +263,11 @@ function registerCommandsSkillsRoutes(authenticated, deps) {
|
|
|
245
263
|
const version = typeof body.version === "string" ? body.version.trim() : void 0;
|
|
246
264
|
const overwrite = body.overwrite === true || body.overwrite === "true" || body.overwrite === "1";
|
|
247
265
|
const provider = parseMarketplaceProviderQuery(typeof body.provider === "string" ? body.provider : void 0);
|
|
266
|
+
const target = optionalSkillInstallTarget(body.target);
|
|
267
|
+
if (body.target != null && !target) return c.json({
|
|
268
|
+
ok: false,
|
|
269
|
+
error: "Expected target to be \"workspace\" or \"global\""
|
|
270
|
+
}, 400);
|
|
248
271
|
if (!name) return c.json({
|
|
249
272
|
ok: false,
|
|
250
273
|
error: "Expected { name: string, version?: string, overwrite?: boolean }"
|
|
@@ -254,7 +277,8 @@ function registerCommandsSkillsRoutes(authenticated, deps) {
|
|
|
254
277
|
name,
|
|
255
278
|
version,
|
|
256
279
|
overwrite,
|
|
257
|
-
provider
|
|
280
|
+
provider,
|
|
281
|
+
target
|
|
258
282
|
});
|
|
259
283
|
return c.json({
|
|
260
284
|
ok: true,
|
|
@@ -267,6 +291,47 @@ function registerCommandsSkillsRoutes(authenticated, deps) {
|
|
|
267
291
|
}, 400);
|
|
268
292
|
}
|
|
269
293
|
});
|
|
294
|
+
authenticated.post("/api/skills/hub/install", async (c) => {
|
|
295
|
+
let body;
|
|
296
|
+
try {
|
|
297
|
+
body = await c.req.json();
|
|
298
|
+
} catch {
|
|
299
|
+
return c.json({
|
|
300
|
+
ok: false,
|
|
301
|
+
error: "Invalid JSON"
|
|
302
|
+
}, 400);
|
|
303
|
+
}
|
|
304
|
+
const source = optionalTrimmedString(body.source);
|
|
305
|
+
if (!source) return c.json({
|
|
306
|
+
ok: false,
|
|
307
|
+
error: "Expected { source: string }"
|
|
308
|
+
}, 400);
|
|
309
|
+
const target = optionalSkillInstallTarget(body.target);
|
|
310
|
+
if (body.target != null && body.target !== "" && !target) return c.json({
|
|
311
|
+
ok: false,
|
|
312
|
+
error: "Expected target to be \"workspace\" or \"global\""
|
|
313
|
+
}, 400);
|
|
314
|
+
try {
|
|
315
|
+
const payload = await service.marketplace.installSkillFromSource({
|
|
316
|
+
source,
|
|
317
|
+
ref: optionalTrimmedString(body.ref),
|
|
318
|
+
path: optionalTrimmedString(body.path),
|
|
319
|
+
skillId: optionalTrimmedString(body.skillId),
|
|
320
|
+
target,
|
|
321
|
+
force: optionalBoolean(body.force) ?? false,
|
|
322
|
+
strictScan: optionalBoolean(body.strictScan) ?? false
|
|
323
|
+
});
|
|
324
|
+
return c.json({
|
|
325
|
+
ok: true,
|
|
326
|
+
payload
|
|
327
|
+
});
|
|
328
|
+
} catch (err) {
|
|
329
|
+
return c.json({
|
|
330
|
+
ok: false,
|
|
331
|
+
error: err instanceof Error ? err.message : "Install failed"
|
|
332
|
+
}, skillHubInstallStatus(err));
|
|
333
|
+
}
|
|
334
|
+
});
|
|
270
335
|
authenticated.post("/api/skills/upload", async (c) => {
|
|
271
336
|
let body;
|
|
272
337
|
try {
|
|
@@ -293,10 +358,17 @@ function registerCommandsSkillsRoutes(authenticated, deps) {
|
|
|
293
358
|
const overwriteRaw = body["overwrite"];
|
|
294
359
|
const skillId = typeof skillIdRaw === "string" && skillIdRaw.trim() ? skillIdRaw.trim() : void 0;
|
|
295
360
|
const overwrite = overwriteRaw === "true" || overwriteRaw === true || overwriteRaw === "1";
|
|
361
|
+
const targetRaw = body["target"];
|
|
362
|
+
const target = optionalSkillInstallTarget(targetRaw);
|
|
363
|
+
if (targetRaw != null && targetRaw !== "" && !target) return c.json({
|
|
364
|
+
ok: false,
|
|
365
|
+
error: "Expected target to be \"workspace\" or \"global\""
|
|
366
|
+
}, 400);
|
|
296
367
|
try {
|
|
297
368
|
const result = service.marketplace.installSkillZip(buf, {
|
|
298
369
|
skillId,
|
|
299
|
-
overwrite
|
|
370
|
+
overwrite,
|
|
371
|
+
target
|
|
300
372
|
});
|
|
301
373
|
return c.json({
|
|
302
374
|
ok: true,
|
|
@@ -315,8 +387,14 @@ function registerCommandsSkillsRoutes(authenticated, deps) {
|
|
|
315
387
|
ok: false,
|
|
316
388
|
error: "Missing id"
|
|
317
389
|
}, 400);
|
|
390
|
+
const targetRaw = c.req.query("target");
|
|
391
|
+
const target = optionalSkillInstallTarget(targetRaw);
|
|
392
|
+
if (targetRaw != null && targetRaw !== "" && !target) return c.json({
|
|
393
|
+
ok: false,
|
|
394
|
+
error: "Expected target to be \"workspace\" or \"global\""
|
|
395
|
+
}, 400);
|
|
318
396
|
try {
|
|
319
|
-
service.marketplace.deleteSkill(id);
|
|
397
|
+
service.marketplace.deleteSkill(id, target);
|
|
320
398
|
return c.json({ ok: true });
|
|
321
399
|
} catch (err) {
|
|
322
400
|
return c.json({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands-skills.js","names":[],"sources":["../../../../../src/gateway/hono/routes/commands-skills.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { commandRegistry } from '../../../chat-commands/index.js';\nimport { isRegisteredProvider } from '../../../agent/skills/skills-marketplace.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\nimport { effectiveWorkspacePathForSession } from '../../../session/session-workspace.js';\nimport { getProjectForSession } from '../../../projects/workspace.js';\nimport { buildReviewContext, resolveGitRoot } from '../../../review/review-git.js';\n\nfunction parseMarketplaceProviderQuery(raw: string | undefined): string | undefined {\n const v = raw?.trim().toLowerCase();\n if (v && isRegisteredProvider(v)) return v;\n return undefined;\n}\n\nexport function registerCommandsSkillsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n // ========== Chat slash commands (CommandRegistry) ==========\n\n authenticated.get('/api/commands', (c) => {\n const all = commandRegistry.list();\n const commands = all\n .filter((cmd) => cmd.scope.includes('global') || cmd.scope.includes('private'))\n .map((cmd) => ({\n id: cmd.id,\n name: cmd.name,\n aliases: cmd.aliases ?? [],\n description: cmd.description,\n category: cmd.category,\n scope: cmd.scope,\n acceptsArgs: cmd.acceptsArgs ?? false,\n examples: cmd.examples ?? [],\n }));\n const extensionCommands = all\n .filter((cmd) => cmd.category === 'extension')\n .map((cmd) => ({\n id: cmd.id,\n name: cmd.name,\n description: cmd.description,\n extensionId: cmd.id.startsWith('ext.') ? cmd.id.split('.')[1] : undefined,\n }));\n return c.json({ ok: true, payload: { commands, extensionCommands } });\n });\n\n authenticated.get('/api/review/context', async (c) => {\n const sessionKey = c.req.query('sessionKey')?.trim() || 'agent:main:main';\n try {\n const workspace = effectiveWorkspacePathForSession(\n service.getConfig(),\n sessionKey,\n null,\n getProjectForSession(sessionKey),\n );\n const cwd = await resolveGitRoot(workspace);\n const payload = await buildReviewContext(cwd);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n {\n ok: false,\n error: {\n code: 'REVIEW_CONTEXT_FAILED',\n message: err instanceof Error ? err.message : 'Failed to load review context',\n },\n },\n 400,\n );\n }\n });\n\n // ========== Skills (managed global skills under ~/.xopc/skills) ==========\n\n authenticated.get('/api/chat/skills', (c) => {\n const agentId = c.req.query('agentId')?.trim() || service.getConfig().agents?.default || 'main';\n const payload = service.marketplace.getAgentSkillsApi(agentId);\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/chat/capabilities', (c) => {\n const payload = service.agentService.getCapabilityCatalog(c.req.query('sessionKey')?.trim());\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills', (c) => {\n const payload = service.marketplace.getSkillsApi();\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills/status', (c) => {\n const payload = service.marketplace.getSkillsStatusApi();\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills/:skillName/content', (c) => {\n const raw = c.req.param('skillName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing skill name' }, 400);\n }\n let skillName: string;\n try {\n skillName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid skill name' }, 400);\n }\n const data = service.marketplace.getSkillMarkdownSource(skillName);\n if (!data) {\n return c.json({ ok: false, error: 'Skill not found' }, 404);\n }\n return c.json({ ok: true, payload: data });\n });\n\n authenticated.post('/api/skills/reload', (c) => {\n service.marketplace.reloadSkills();\n return c.json({ ok: true });\n });\n\n authenticated.patch('/api/skills/enabled', async (c) => {\n let body: { skillName?: unknown; enabled?: unknown };\n try {\n body = (await c.req.json()) as { skillName?: unknown; enabled?: unknown };\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const skillName = typeof body.skillName === 'string' ? body.skillName.trim() : '';\n const enabled = body.enabled;\n if (!skillName || typeof enabled !== 'boolean') {\n return c.json({ ok: false, error: 'Expected { skillName: string, enabled: boolean }' }, 400);\n }\n try {\n service.marketplace.patchSkillEnabled(skillName, enabled);\n return c.json({ ok: true });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Update failed' },\n 400,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace', async (c) => {\n const q = c.req.query('q')?.trim() ?? '';\n const pageRaw = c.req.query('page');\n const pageSizeRaw = c.req.query('pageSize');\n const sortRaw = c.req.query('sort');\n const page = pageRaw != null && pageRaw !== '' ? Math.max(1, Number(pageRaw) || 1) : undefined;\n const pageSize =\n pageSizeRaw != null && pageSizeRaw !== ''\n ? Math.min(50, Math.max(1, Number(pageSizeRaw) || 20))\n : undefined;\n const sort =\n sortRaw === 'newest' || sortRaw === 'downloads' ? sortRaw : undefined;\n const category = c.req.query('category')?.trim() ?? '';\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n try {\n const payload = await service.marketplace.fetchSkillsCatalog(\n {\n q: q || undefined,\n page,\n pageSize,\n sort,\n category: category || undefined,\n },\n provider,\n );\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace/provider', async (c) => {\n const info = await service.marketplace.getSkillsProvider();\n return c.json({ ok: true, payload: info });\n });\n\n /** All registered marketplace providers (built-in + extension-contributed). */\n authenticated.get('/api/skills/marketplace/providers', async (c) => {\n const [providers, current] = await Promise.all([\n service.marketplace.getSkillsProviders(),\n service.marketplace.getSkillsProvider(),\n ]);\n return c.json({ ok: true, payload: { providers, current: current.provider } });\n });\n\n authenticated.get('/api/skills/marketplace/categories', async (c) => {\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n try {\n const payload = await service.marketplace.fetchSkillsCategories(provider);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace categories failed' },\n 502,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace/packages/:pkgName', async (c) => {\n const raw = c.req.param('pkgName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing package name' }, 400);\n }\n let pkgName: string;\n try {\n pkgName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid package name' }, 400);\n }\n try {\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n const payload = await service.marketplace.fetchSkillsPackageDetail(pkgName, provider);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.post('/api/skills/marketplace/install', async (c) => {\n let body: { name?: unknown; version?: unknown; overwrite?: unknown; provider?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const name = typeof body.name === 'string' ? body.name.trim() : '';\n const version = typeof body.version === 'string' ? body.version.trim() : undefined;\n const overwrite =\n body.overwrite === true ||\n body.overwrite === 'true' ||\n body.overwrite === '1';\n const provider = parseMarketplaceProviderQuery(\n typeof body.provider === 'string' ? body.provider : undefined,\n );\n if (!name) {\n return c.json({ ok: false, error: 'Expected { name: string, version?: string, overwrite?: boolean }' }, 400);\n }\n try {\n const payload = await service.marketplace.installSkill({ name, version, overwrite, provider });\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.post('/api/skills/upload', async (c) => {\n let body: Record<string, unknown>;\n try {\n body = await c.req.parseBody({ all: true });\n } catch {\n return c.json({ ok: false, error: 'Invalid multipart body' }, 400);\n }\n const file = body['file'];\n if (!file || typeof file !== 'object') {\n return c.json({ ok: false, error: 'Missing file field' }, 400);\n }\n let buf: Buffer;\n if (file instanceof File) {\n buf = Buffer.from(await file.arrayBuffer());\n } else if (typeof (file as Blob).arrayBuffer === 'function') {\n buf = Buffer.from(await (file as Blob).arrayBuffer());\n } else {\n return c.json({ ok: false, error: 'Invalid file upload' }, 400);\n }\n const skillIdRaw = body['skillId'];\n const overwriteRaw = body['overwrite'];\n const skillId = typeof skillIdRaw === 'string' && skillIdRaw.trim() ? skillIdRaw.trim() : undefined;\n const overwrite =\n overwriteRaw === 'true' ||\n overwriteRaw === true ||\n overwriteRaw === '1';\n\n try {\n const result = service.marketplace.installSkillZip(buf, { skillId, overwrite });\n return c.json({ ok: true, payload: result });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.delete('/api/skills/:id', (c) => {\n const id = c.req.param('id');\n if (!id) {\n return c.json({ ok: false, error: 'Missing id' }, 400);\n }\n try {\n service.marketplace.deleteSkill(id);\n return c.json({ ok: true });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Delete failed' },\n 400,\n );\n }\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"commands-skills.js","names":[],"sources":["../../../../../src/gateway/hono/routes/commands-skills.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { commandRegistry } from '../../../chat-commands/index.js';\nimport { isRegisteredProvider } from '../../../agent/skills/skills-marketplace.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\nimport { effectiveWorkspacePathForSession } from '../../../session/session-workspace.js';\nimport { getProjectForSession } from '../../../projects/workspace.js';\nimport { buildReviewContext, resolveGitRoot } from '../../../review/review-git.js';\nimport {\n isSkillInstallTarget,\n type SkillInstallTarget,\n} from '../../../agent/skills/install-target.js';\n\nfunction parseMarketplaceProviderQuery(raw: string | undefined): string | undefined {\n const v = raw?.trim().toLowerCase();\n if (v && isRegisteredProvider(v)) return v;\n return undefined;\n}\n\nfunction optionalTrimmedString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction optionalBoolean(value: unknown): boolean | undefined {\n if (value === true || value === 'true' || value === '1') return true;\n if (value === false || value === 'false' || value === '0') return false;\n return undefined;\n}\n\nfunction optionalSkillInstallTarget(value: unknown): SkillInstallTarget | undefined {\n if (value == null || value === '') return undefined;\n return isSkillInstallTarget(value) ? value : undefined;\n}\n\nfunction skillHubInstallStatus(err: unknown): 400 | 409 | 502 {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes('already exists')) return 409;\n if (\n message.startsWith('HTTP ') ||\n message.includes('fetching archive') ||\n message.includes('git clone failed') ||\n message.includes('Git operation failed')\n ) {\n return 502;\n }\n return 400;\n}\n\nexport function registerCommandsSkillsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n // ========== Chat slash commands (CommandRegistry) ==========\n\n authenticated.get('/api/commands', (c) => {\n const all = commandRegistry.list();\n const commands = all\n .filter((cmd) => cmd.scope.includes('global') || cmd.scope.includes('private'))\n .map((cmd) => ({\n id: cmd.id,\n name: cmd.name,\n aliases: cmd.aliases ?? [],\n description: cmd.description,\n category: cmd.category,\n scope: cmd.scope,\n acceptsArgs: cmd.acceptsArgs ?? false,\n examples: cmd.examples ?? [],\n }));\n const extensionCommands = all\n .filter((cmd) => cmd.category === 'extension')\n .map((cmd) => ({\n id: cmd.id,\n name: cmd.name,\n description: cmd.description,\n extensionId: cmd.id.startsWith('ext.') ? cmd.id.split('.')[1] : undefined,\n }));\n return c.json({ ok: true, payload: { commands, extensionCommands } });\n });\n\n authenticated.get('/api/review/context', async (c) => {\n const sessionKey = c.req.query('sessionKey')?.trim() || 'agent:main:main';\n try {\n const workspace = effectiveWorkspacePathForSession(\n service.getConfig(),\n sessionKey,\n null,\n getProjectForSession(sessionKey),\n );\n const cwd = await resolveGitRoot(workspace);\n const payload = await buildReviewContext(cwd);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n {\n ok: false,\n error: {\n code: 'REVIEW_CONTEXT_FAILED',\n message: err instanceof Error ? err.message : 'Failed to load review context',\n },\n },\n 400,\n );\n }\n });\n\n // ========== Skills (managed global skills under ~/.xopc/skills) ==========\n\n authenticated.get('/api/chat/skills', (c) => {\n const agentId = c.req.query('agentId')?.trim() || service.getConfig().agents?.default || 'main';\n const payload = service.marketplace.getAgentSkillsApi(agentId);\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/chat/capabilities', (c) => {\n const payload = service.agentService.getCapabilityCatalog(c.req.query('sessionKey')?.trim());\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills', (c) => {\n const payload = service.marketplace.getSkillsApi();\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills/status', (c) => {\n const payload = service.marketplace.getSkillsStatusApi();\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/skills/:skillName/content', (c) => {\n const raw = c.req.param('skillName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing skill name' }, 400);\n }\n let skillName: string;\n try {\n skillName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid skill name' }, 400);\n }\n const data = service.marketplace.getSkillMarkdownSource(skillName);\n if (!data) {\n return c.json({ ok: false, error: 'Skill not found' }, 404);\n }\n return c.json({ ok: true, payload: data });\n });\n\n authenticated.post('/api/skills/reload', (c) => {\n service.marketplace.reloadSkills();\n return c.json({ ok: true });\n });\n\n authenticated.patch('/api/skills/enabled', async (c) => {\n let body: { skillName?: unknown; enabled?: unknown };\n try {\n body = (await c.req.json()) as { skillName?: unknown; enabled?: unknown };\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const skillName = typeof body.skillName === 'string' ? body.skillName.trim() : '';\n const enabled = body.enabled;\n if (!skillName || typeof enabled !== 'boolean') {\n return c.json({ ok: false, error: 'Expected { skillName: string, enabled: boolean }' }, 400);\n }\n try {\n service.marketplace.patchSkillEnabled(skillName, enabled);\n return c.json({ ok: true });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Update failed' },\n 400,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace', async (c) => {\n const q = c.req.query('q')?.trim() ?? '';\n const pageRaw = c.req.query('page');\n const pageSizeRaw = c.req.query('pageSize');\n const sortRaw = c.req.query('sort');\n const page = pageRaw != null && pageRaw !== '' ? Math.max(1, Number(pageRaw) || 1) : undefined;\n const pageSize =\n pageSizeRaw != null && pageSizeRaw !== ''\n ? Math.min(50, Math.max(1, Number(pageSizeRaw) || 20))\n : undefined;\n const sort =\n sortRaw === 'newest' || sortRaw === 'downloads' ? sortRaw : undefined;\n const category = c.req.query('category')?.trim() ?? '';\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n try {\n const payload = await service.marketplace.fetchSkillsCatalog(\n {\n q: q || undefined,\n page,\n pageSize,\n sort,\n category: category || undefined,\n },\n provider,\n );\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace/provider', async (c) => {\n const info = await service.marketplace.getSkillsProvider();\n return c.json({ ok: true, payload: info });\n });\n\n /** All registered marketplace providers (built-in + extension-contributed). */\n authenticated.get('/api/skills/marketplace/providers', async (c) => {\n const [providers, current] = await Promise.all([\n service.marketplace.getSkillsProviders(),\n service.marketplace.getSkillsProvider(),\n ]);\n return c.json({ ok: true, payload: { providers, current: current.provider } });\n });\n\n authenticated.get('/api/skills/marketplace/categories', async (c) => {\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n try {\n const payload = await service.marketplace.fetchSkillsCategories(provider);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace categories failed' },\n 502,\n );\n }\n });\n\n authenticated.get('/api/skills/marketplace/packages/:pkgName', async (c) => {\n const raw = c.req.param('pkgName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing package name' }, 400);\n }\n let pkgName: string;\n try {\n pkgName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid package name' }, 400);\n }\n try {\n const provider = parseMarketplaceProviderQuery(c.req.query('provider'));\n const payload = await service.marketplace.fetchSkillsPackageDetail(pkgName, provider);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.post('/api/skills/marketplace/install', async (c) => {\n let body: {\n name?: unknown;\n version?: unknown;\n overwrite?: unknown;\n provider?: unknown;\n target?: unknown;\n };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const name = typeof body.name === 'string' ? body.name.trim() : '';\n const version = typeof body.version === 'string' ? body.version.trim() : undefined;\n const overwrite =\n body.overwrite === true ||\n body.overwrite === 'true' ||\n body.overwrite === '1';\n const provider = parseMarketplaceProviderQuery(\n typeof body.provider === 'string' ? body.provider : undefined,\n );\n const target = optionalSkillInstallTarget(body.target);\n if (body.target != null && !target) {\n return c.json({ ok: false, error: 'Expected target to be \"workspace\" or \"global\"' }, 400);\n }\n if (!name) {\n return c.json({ ok: false, error: 'Expected { name: string, version?: string, overwrite?: boolean }' }, 400);\n }\n try {\n const payload = await service.marketplace.installSkill({ name, version, overwrite, provider, target });\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.post('/api/skills/hub/install', async (c) => {\n let body: Record<string, unknown>;\n try {\n body = (await c.req.json()) as Record<string, unknown>;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n\n const source = optionalTrimmedString(body.source);\n if (!source) {\n return c.json({ ok: false, error: 'Expected { source: string }' }, 400);\n }\n const target = optionalSkillInstallTarget(body.target);\n if (body.target != null && body.target !== '' && !target) {\n return c.json({ ok: false, error: 'Expected target to be \"workspace\" or \"global\"' }, 400);\n }\n\n try {\n const payload = await service.marketplace.installSkillFromSource({\n source,\n ref: optionalTrimmedString(body.ref),\n path: optionalTrimmedString(body.path),\n skillId: optionalTrimmedString(body.skillId),\n target,\n force: optionalBoolean(body.force) ?? false,\n strictScan: optionalBoolean(body.strictScan) ?? false,\n });\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n skillHubInstallStatus(err),\n );\n }\n });\n\n authenticated.post('/api/skills/upload', async (c) => {\n let body: Record<string, unknown>;\n try {\n body = await c.req.parseBody({ all: true });\n } catch {\n return c.json({ ok: false, error: 'Invalid multipart body' }, 400);\n }\n const file = body['file'];\n if (!file || typeof file !== 'object') {\n return c.json({ ok: false, error: 'Missing file field' }, 400);\n }\n let buf: Buffer;\n if (file instanceof File) {\n buf = Buffer.from(await file.arrayBuffer());\n } else if (typeof (file as Blob).arrayBuffer === 'function') {\n buf = Buffer.from(await (file as Blob).arrayBuffer());\n } else {\n return c.json({ ok: false, error: 'Invalid file upload' }, 400);\n }\n const skillIdRaw = body['skillId'];\n const overwriteRaw = body['overwrite'];\n const skillId = typeof skillIdRaw === 'string' && skillIdRaw.trim() ? skillIdRaw.trim() : undefined;\n const overwrite =\n overwriteRaw === 'true' ||\n overwriteRaw === true ||\n overwriteRaw === '1';\n const targetRaw = body['target'];\n const target = optionalSkillInstallTarget(targetRaw);\n if (targetRaw != null && targetRaw !== '' && !target) {\n return c.json({ ok: false, error: 'Expected target to be \"workspace\" or \"global\"' }, 400);\n }\n\n try {\n const result = service.marketplace.installSkillZip(buf, { skillId, overwrite, target });\n return c.json({ ok: true, payload: result });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.delete('/api/skills/:id', (c) => {\n const id = c.req.param('id');\n if (!id) {\n return c.json({ ok: false, error: 'Missing id' }, 400);\n }\n const targetRaw = c.req.query('target');\n const target = optionalSkillInstallTarget(targetRaw);\n if (targetRaw != null && targetRaw !== '' && !target) {\n return c.json({ ok: false, error: 'Expected target to be \"workspace\" or \"global\"' }, 400);\n }\n try {\n service.marketplace.deleteSkill(id, target);\n return c.json({ ok: true });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Delete failed' },\n 400,\n );\n }\n });\n}\n"],"mappings":"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"}
|
|
@@ -2,12 +2,12 @@ import { createConnectorSetupSecretRequest, submitConnectorSetupSecret } from ".
|
|
|
2
2
|
import { executeComposioTool, getComposioToolkitScope, listComposioConnections, listComposioTools, setComposioToolkitScope, startComposioAuthorize } from "../../../connectors/composio.js";
|
|
3
3
|
import { listConnectorProviders } from "../../../connectors/providers.js";
|
|
4
4
|
import { getConnectorDefinition, listConnectorCatalog } from "../../../connectors/catalog.js";
|
|
5
|
-
import { appendComposioTriggerEvent, listComposioTriggerEvents } from "../../../connectors/composio-triggers.js";
|
|
6
5
|
import { recordConnectorHealthUsage } from "../../../connectors/usage.js";
|
|
7
6
|
import { getConnectorInstance, listConnectorInstances } from "../../../connectors/instances.js";
|
|
8
|
-
import { previewConnectorDefinition, testConnectorInstance } from "../../../connectors/health.js";
|
|
9
7
|
import { completeConnectorOAuth, startConnectorOAuth } from "../../../connectors/oauth.js";
|
|
10
8
|
import { installConnector, installConnectorDefinition, uninstallConnector, updateConnectorConfig } from "../../../connectors/install.js";
|
|
9
|
+
import { appendComposioTriggerEvent, listComposioTriggerEvents } from "../../../connectors/composio-triggers.js";
|
|
10
|
+
import { previewConnectorDefinition, testConnectorInstance } from "../../../connectors/health.js";
|
|
11
11
|
import { setConnectorEnabled } from "../../../connectors/lifecycle.js";
|
|
12
12
|
import { isConnectorRegistrySource, listConnectorRegistries, searchConnectorRegistries } from "../../../connectors/registries/search.js";
|
|
13
13
|
//#region src/gateway/hono/routes/connectors.ts
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { buildSessionKey, init_session_key, sanitizeSegment } from "../../../routing/session-key.js";
|
|
2
2
|
import { getDefaultAgentId, init_resolve_route } from "../../../routing/resolve-route.js";
|
|
3
3
|
import { GoalService, normalizeGoalUiLocale } from "../../../goals/goal-service.js";
|
|
4
|
+
import { draftGoalContract } from "../../../goals/goal-contract-draft.js";
|
|
5
|
+
import { reviewGoalEvidenceRequirement } from "../../../goals/goal-evidence-review.js";
|
|
4
6
|
import "../../../goals/index.js";
|
|
5
7
|
import { createWorkflowCatalog } from "../../../agent/workflow/catalog.js";
|
|
6
8
|
import { resolveProjectAgentId } from "../../../projects/project-agent.js";
|
|
@@ -25,6 +27,27 @@ function parseBodyGoalStatus(raw) {
|
|
|
25
27
|
function parsePriority(raw) {
|
|
26
28
|
return raw === "low" || raw === "normal" || raw === "high" ? raw : void 0;
|
|
27
29
|
}
|
|
30
|
+
function parseGoalContract(raw) {
|
|
31
|
+
if (raw === void 0) return void 0;
|
|
32
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
33
|
+
const value = raw;
|
|
34
|
+
const list = (candidate) => {
|
|
35
|
+
if (candidate === void 0) return void 0;
|
|
36
|
+
if (!Array.isArray(candidate) || candidate.some((item) => typeof item !== "string")) return void 0;
|
|
37
|
+
return candidate.map((item) => item.trim()).filter(Boolean).slice(0, 20);
|
|
38
|
+
};
|
|
39
|
+
const evidencePlan = list(value.evidencePlan);
|
|
40
|
+
const criteria = list(value.criteria);
|
|
41
|
+
if (value.evidencePlan !== void 0 && !evidencePlan || value.criteria !== void 0 && !criteria) return null;
|
|
42
|
+
if (value.objective !== void 0 && typeof value.objective !== "string") return null;
|
|
43
|
+
if (value.scopeBoundary !== void 0 && typeof value.scopeBoundary !== "string") return null;
|
|
44
|
+
return {
|
|
45
|
+
objective: typeof value.objective === "string" ? value.objective.trim() : void 0,
|
|
46
|
+
scopeBoundary: typeof value.scopeBoundary === "string" ? value.scopeBoundary.trim() : void 0,
|
|
47
|
+
evidencePlan,
|
|
48
|
+
criteria
|
|
49
|
+
};
|
|
50
|
+
}
|
|
28
51
|
function maxBase64CharsForBinary(maxBinaryBytes) {
|
|
29
52
|
return 4 * Math.ceil(maxBinaryBytes / 3);
|
|
30
53
|
}
|
|
@@ -259,6 +282,11 @@ function registerGoalsRoutes(authenticated, deps) {
|
|
|
259
282
|
ok: false,
|
|
260
283
|
error: "Missing title"
|
|
261
284
|
}, 400);
|
|
285
|
+
const contract = parseGoalContract(body.contract);
|
|
286
|
+
if (contract === null) return c.json({
|
|
287
|
+
ok: false,
|
|
288
|
+
error: "Invalid goal contract"
|
|
289
|
+
}, 400);
|
|
262
290
|
const sessionKey = typeof body.sessionKey === "string" && body.sessionKey.trim() ? body.sessionKey.trim() : void 0;
|
|
263
291
|
const contextMessage = parseUserTurnInput(body.contextMessage) ?? { text: "" };
|
|
264
292
|
const attachmentError = validateUserTurnAttachments(contextMessage.attachments);
|
|
@@ -291,6 +319,7 @@ function registerGoalsRoutes(authenticated, deps) {
|
|
|
291
319
|
uiLocale: normalizeGoalUiLocale(body.uiLocale),
|
|
292
320
|
source: body.source === "cli" || body.source === "cron" || body.source === "workflow" || body.source === "channel" || body.source === "api" ? body.source : "chat",
|
|
293
321
|
projectId,
|
|
322
|
+
contract,
|
|
294
323
|
config: cfg()
|
|
295
324
|
});
|
|
296
325
|
goals.setContextMessage({
|
|
@@ -303,6 +332,59 @@ function registerGoalsRoutes(authenticated, deps) {
|
|
|
303
332
|
goal: goals.get(goal.id)
|
|
304
333
|
});
|
|
305
334
|
});
|
|
335
|
+
authenticated.post("/api/goals/contract/draft", async (c) => {
|
|
336
|
+
const body = await c.req.json().catch(() => ({}));
|
|
337
|
+
const title = typeof body.title === "string" ? body.title.trim() : "";
|
|
338
|
+
if (!title) return c.json({
|
|
339
|
+
ok: false,
|
|
340
|
+
error: "Missing title"
|
|
341
|
+
}, 400);
|
|
342
|
+
const parsed = parseGoalContract({ criteria: body.criteria });
|
|
343
|
+
if (!parsed) return c.json({
|
|
344
|
+
ok: false,
|
|
345
|
+
error: "Invalid acceptance criteria"
|
|
346
|
+
}, 400);
|
|
347
|
+
const modelRef = typeof body.modelRef === "string" && body.modelRef.trim() ? body.modelRef.trim() : typeof body.judgeModelRef === "string" && body.judgeModelRef.trim() ? body.judgeModelRef.trim() : cfg()?.goals?.judgeModelRef;
|
|
348
|
+
const result = await draftGoalContract({
|
|
349
|
+
title,
|
|
350
|
+
context: typeof body.context === "string" ? body.context : void 0,
|
|
351
|
+
criteria: parsed.criteria,
|
|
352
|
+
uiLocale: normalizeGoalUiLocale(body.uiLocale),
|
|
353
|
+
modelRef
|
|
354
|
+
});
|
|
355
|
+
return c.json({
|
|
356
|
+
ok: true,
|
|
357
|
+
...result
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
authenticated.get("/api/goals/:goalId/contract", async (c) => {
|
|
361
|
+
const goal = goals.get(c.req.param("goalId"));
|
|
362
|
+
if (!goal) return c.json({
|
|
363
|
+
ok: false,
|
|
364
|
+
error: "Goal not found"
|
|
365
|
+
}, 404);
|
|
366
|
+
return c.json({
|
|
367
|
+
ok: true,
|
|
368
|
+
contract: goal.contract ?? null
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
authenticated.put("/api/goals/:goalId/contract", async (c) => {
|
|
372
|
+
const contract = parseGoalContract(await c.req.json().catch(() => ({})));
|
|
373
|
+
if (!contract) return c.json({
|
|
374
|
+
ok: false,
|
|
375
|
+
error: "Invalid goal contract"
|
|
376
|
+
}, 400);
|
|
377
|
+
const goal = goals.setContract(c.req.param("goalId"), contract);
|
|
378
|
+
if (!goal) return c.json({
|
|
379
|
+
ok: false,
|
|
380
|
+
error: "Goal not found"
|
|
381
|
+
}, 404);
|
|
382
|
+
return c.json({
|
|
383
|
+
ok: true,
|
|
384
|
+
goal,
|
|
385
|
+
contract: goal.contract
|
|
386
|
+
});
|
|
387
|
+
});
|
|
306
388
|
authenticated.get("/api/goals/:goalId/workflow-runs", async (c) => {
|
|
307
389
|
const goalId = c.req.param("goalId");
|
|
308
390
|
const goal = goals.get(goalId);
|
|
@@ -607,8 +689,16 @@ function registerGoalsRoutes(authenticated, deps) {
|
|
|
607
689
|
});
|
|
608
690
|
});
|
|
609
691
|
authenticated.post("/api/goals/:goalId/complete", async (c) => {
|
|
610
|
-
const
|
|
611
|
-
const
|
|
692
|
+
const goalId = c.req.param("goalId");
|
|
693
|
+
const before = goals.get(goalId);
|
|
694
|
+
const readiness = goals.getCompletionReadiness(goalId);
|
|
695
|
+
if (readiness && !readiness.ready) return c.json({
|
|
696
|
+
ok: false,
|
|
697
|
+
error: "Goal completion evidence is still required",
|
|
698
|
+
missingEvidence: readiness.missingEvidence,
|
|
699
|
+
pendingApproval: readiness.pendingApproval
|
|
700
|
+
}, 409);
|
|
701
|
+
const goal = goals.complete(goalId);
|
|
612
702
|
if (!goal) return c.json({
|
|
613
703
|
ok: false,
|
|
614
704
|
error: "Goal not found"
|
|
@@ -733,6 +823,17 @@ function registerGoalsRoutes(authenticated, deps) {
|
|
|
733
823
|
evidence: goals.listEvidence(goalId, parseLimit(c.req.query("limit"), 100))
|
|
734
824
|
});
|
|
735
825
|
});
|
|
826
|
+
authenticated.get("/api/goals/:goalId/evidence-requirements", async (c) => {
|
|
827
|
+
const goalId = c.req.param("goalId");
|
|
828
|
+
if (!goals.get(goalId)) return c.json({
|
|
829
|
+
ok: false,
|
|
830
|
+
error: "Goal not found"
|
|
831
|
+
}, 404);
|
|
832
|
+
return c.json({
|
|
833
|
+
ok: true,
|
|
834
|
+
requirements: goals.listEvidenceRequirements(goalId)
|
|
835
|
+
});
|
|
836
|
+
});
|
|
736
837
|
authenticated.post("/api/goals/:goalId/evidence", async (c) => {
|
|
737
838
|
const goalId = c.req.param("goalId");
|
|
738
839
|
if (!goals.get(goalId)) return c.json({
|
|
@@ -742,6 +843,7 @@ function registerGoalsRoutes(authenticated, deps) {
|
|
|
742
843
|
const body = await c.req.json().catch(() => ({}));
|
|
743
844
|
const title = typeof body.title === "string" ? body.title.trim() : "";
|
|
744
845
|
const kind = body.kind;
|
|
846
|
+
const requirementId = typeof body.requirementId === "string" ? body.requirementId.trim() : "";
|
|
745
847
|
if (!title) return c.json({
|
|
746
848
|
ok: false,
|
|
747
849
|
error: "Missing title"
|
|
@@ -750,6 +852,10 @@ function registerGoalsRoutes(authenticated, deps) {
|
|
|
750
852
|
ok: false,
|
|
751
853
|
error: "Invalid evidence kind"
|
|
752
854
|
}, 400);
|
|
855
|
+
if (requirementId && !goals.listEvidenceRequirements(goalId).some((item) => item.id === requirementId)) return c.json({
|
|
856
|
+
ok: false,
|
|
857
|
+
error: "Evidence requirement not found"
|
|
858
|
+
}, 404);
|
|
753
859
|
const evidence = goals.addEvidence({
|
|
754
860
|
goalId,
|
|
755
861
|
runId: typeof body.runId === "string" ? body.runId : void 0,
|
|
@@ -759,9 +865,112 @@ function registerGoalsRoutes(authenticated, deps) {
|
|
|
759
865
|
uri: typeof body.uri === "string" ? body.uri : void 0,
|
|
760
866
|
data: body.data
|
|
761
867
|
});
|
|
868
|
+
const requirement = requirementId ? goals.linkEvidenceRequirement({
|
|
869
|
+
goalId,
|
|
870
|
+
requirementId,
|
|
871
|
+
evidenceId: evidence.id,
|
|
872
|
+
linkedBy: "user"
|
|
873
|
+
}) : void 0;
|
|
874
|
+
return c.json({
|
|
875
|
+
ok: true,
|
|
876
|
+
evidence: {
|
|
877
|
+
...evidence,
|
|
878
|
+
requirementIds: requirement ? [requirement.id] : []
|
|
879
|
+
},
|
|
880
|
+
requirement
|
|
881
|
+
});
|
|
882
|
+
});
|
|
883
|
+
authenticated.post("/api/goals/:goalId/evidence-requirements/:requirementId/link", async (c) => {
|
|
884
|
+
const goalId = c.req.param("goalId");
|
|
885
|
+
const body = await c.req.json().catch(() => ({}));
|
|
886
|
+
const evidenceId = typeof body.evidenceId === "string" ? body.evidenceId.trim() : "";
|
|
887
|
+
if (!evidenceId) return c.json({
|
|
888
|
+
ok: false,
|
|
889
|
+
error: "Missing evidence id"
|
|
890
|
+
}, 400);
|
|
891
|
+
const requirement = goals.linkEvidenceRequirement({
|
|
892
|
+
goalId,
|
|
893
|
+
requirementId: c.req.param("requirementId"),
|
|
894
|
+
evidenceId,
|
|
895
|
+
linkedBy: "user"
|
|
896
|
+
});
|
|
897
|
+
if (!requirement) return c.json({
|
|
898
|
+
ok: false,
|
|
899
|
+
error: "Evidence requirement or evidence not found"
|
|
900
|
+
}, 404);
|
|
901
|
+
return c.json({
|
|
902
|
+
ok: true,
|
|
903
|
+
requirement
|
|
904
|
+
});
|
|
905
|
+
});
|
|
906
|
+
authenticated.post("/api/goals/:goalId/evidence-requirements/:requirementId/review", async (c) => {
|
|
907
|
+
const goalId = c.req.param("goalId");
|
|
908
|
+
const goal = goals.get(goalId);
|
|
909
|
+
if (!goal) return c.json({
|
|
910
|
+
ok: false,
|
|
911
|
+
error: "Goal not found"
|
|
912
|
+
}, 404);
|
|
913
|
+
const requirement = goal.evidenceRequirements.find((item) => item.id === c.req.param("requirementId"));
|
|
914
|
+
if (!requirement) return c.json({
|
|
915
|
+
ok: false,
|
|
916
|
+
error: "Evidence requirement not found"
|
|
917
|
+
}, 404);
|
|
918
|
+
const body = await c.req.json().catch(() => ({}));
|
|
919
|
+
const evidenceById = new Map(goals.listEvidence(goalId, 500).map((item) => [item.id, item]));
|
|
920
|
+
const review = await reviewGoalEvidenceRequirement({
|
|
921
|
+
requirement,
|
|
922
|
+
evidence: requirement.evidenceIds.flatMap((id) => {
|
|
923
|
+
const item = evidenceById.get(id);
|
|
924
|
+
return item ? [item] : [];
|
|
925
|
+
}),
|
|
926
|
+
modelRef: typeof body.modelRef === "string" && body.modelRef.trim() ? body.modelRef.trim() : goal.judgeModelRef
|
|
927
|
+
});
|
|
928
|
+
const status = review.verdict === "approved" ? "ai_verified" : review.verdict === "rejected" ? "rejected" : "pending";
|
|
929
|
+
const updated = goals.reviewEvidenceRequirement({
|
|
930
|
+
goalId,
|
|
931
|
+
requirementId: requirement.id,
|
|
932
|
+
status,
|
|
933
|
+
reason: review.reason,
|
|
934
|
+
confidence: review.confidence,
|
|
935
|
+
reviewedBy: review.generated ? "ai" : "system"
|
|
936
|
+
});
|
|
937
|
+
return c.json({
|
|
938
|
+
ok: true,
|
|
939
|
+
requirement: updated,
|
|
940
|
+
review
|
|
941
|
+
});
|
|
942
|
+
});
|
|
943
|
+
authenticated.post("/api/goals/:goalId/evidence-requirements/:requirementId/approve", async (c) => {
|
|
944
|
+
const goalId = c.req.param("goalId");
|
|
945
|
+
const body = await c.req.json().catch(() => ({}));
|
|
946
|
+
const existing = goals.get(goalId);
|
|
947
|
+
if (!existing) return c.json({
|
|
948
|
+
ok: false,
|
|
949
|
+
error: "Goal not found"
|
|
950
|
+
}, 404);
|
|
951
|
+
const existingRequirement = existing.evidenceRequirements.find((item) => item.id === c.req.param("requirementId"));
|
|
952
|
+
if (!existingRequirement) return c.json({
|
|
953
|
+
ok: false,
|
|
954
|
+
error: "Evidence requirement not found"
|
|
955
|
+
}, 404);
|
|
956
|
+
if (existingRequirement.evidenceIds.length === 0) return c.json({
|
|
957
|
+
ok: false,
|
|
958
|
+
error: "Link evidence before approving this requirement"
|
|
959
|
+
}, 409);
|
|
960
|
+
const requirement = goals.reviewEvidenceRequirement({
|
|
961
|
+
goalId,
|
|
962
|
+
requirementId: c.req.param("requirementId"),
|
|
963
|
+
status: "approved",
|
|
964
|
+
reason: typeof body.reason === "string" && body.reason.trim() ? body.reason.trim() : "Approved by a user after reviewing the linked evidence.",
|
|
965
|
+
reviewedBy: "user"
|
|
966
|
+
});
|
|
967
|
+
if (!requirement) return c.json({
|
|
968
|
+
ok: false,
|
|
969
|
+
error: "Evidence requirement not found"
|
|
970
|
+
}, 404);
|
|
762
971
|
return c.json({
|
|
763
972
|
ok: true,
|
|
764
|
-
|
|
973
|
+
requirement
|
|
765
974
|
});
|
|
766
975
|
});
|
|
767
976
|
authenticated.post("/api/goals/:goalId/checklist", async (c) => {
|