@xopcai/xopc 0.0.396 → 0.0.398
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-DwTaeL1e.js → agent-avatar-dicebear-Q-lKLSrc.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CobxTBV_.js +1 -0
- package/dist/gateway/static/root/assets/agents-Bgmmue5K.js +77 -0
- package/dist/gateway/static/root/assets/{agents-admin-api-BjGOUrAf.js → agents-admin-api-DvSe10zu.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-B1ApwlFh.js → app-management-settings-panel-CB_W2ano.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-Avd_jVji.js → appearance-settings-B-ppSGBm.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-3qUgsGui.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-C26WGbj9.js → archive-plugin-CeQrQ693.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-T3FSuURJ.js → automations-page-Cc9vZanv.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-Bc4c_AEq.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CLaLkM3M.js → binary-plugins-BqaVBv1R.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CB4oRyM5.js → block-editor-B4ij8nZi.js} +40 -40
- package/dist/gateway/static/root/assets/{browser-automation-inputs-0nkk3bLA.js → browser-automation-inputs-DngvcZH9.js} +1 -1
- package/dist/gateway/static/root/assets/browser-automations-page-CdqwXyYq.js +3 -0
- package/dist/gateway/static/root/assets/browser-settings-page-CJT0rB-I.js +3 -0
- package/dist/gateway/static/root/assets/{capabilities-CTfLd_UE.js → capabilities-glv1DeRI.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-page-C56VsP0Y.js +2 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DZiA8JIq.js +8 -0
- package/dist/gateway/static/root/assets/{capability-header-actions-Br5PchG2.js → capability-header-actions-Cu-ATcJq.js} +1 -1
- package/dist/gateway/static/root/assets/capability-links--dcwUjgv.js +1 -0
- package/dist/gateway/static/root/assets/channels-gIjZtYnV.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-Cl0hAav9.js → chat-terminal-dock-COdvmTgN.js} +2 -2
- package/dist/gateway/static/root/assets/computer-settings-page-C1XHsuI8.js +1 -0
- package/dist/gateway/static/root/assets/{connector-service-page-AqsoqTnF.js → connector-service-page-Cv2bhnQ5.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-SmKItq0N.js +1 -0
- package/dist/gateway/static/root/assets/{date-picker-CyFehuto.js → date-picker-CCnqYwy0.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-Vu_5QGGJ.js → dependency-picker-nt5ruIio.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Dw9k0Z2p.js → desktop-pet-Bn8xj1v3.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DKqkhvxu.js → desktop-pet-settings-Cbl1J_VE.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-4l4ESMon.js → device-pairing-wizard-Tadg9co1.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-7svbL2tR.js → directory-picker-path-field-DuE5ez1E.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CFa6PCBV.js → extension-debug-page-jsNxwqNi.js} +1 -1
- package/dist/gateway/static/root/assets/extension-page-N_rBjYX8.js +1 -0
- package/dist/gateway/static/root/assets/extension-settings-page-7qAdvlRB.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-swr-Di9g6pE8.js → gateway-config-swr-DAir1JsW.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-realtime-2-o7qk92.js → gateway-realtime-dE0XrVAT.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-CPlVuu0d.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-ViqOhx_m.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BCUswcVy.js → gateway-startup-retry-CqyGHM2M.js} +1 -1
- package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-DzEeyJpH.js → highlighted-body-KQOG7T2V-XrkWdmrk.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-C_Xn_Kkz.js +2 -0
- package/dist/gateway/static/root/assets/{image-generation-api-Zo56ZmKs.js → image-generation-api-CmHdM2uL.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-C_PPaOFv.js → imports-page-B-dnvHP_.js} +1 -1
- package/dist/gateway/static/root/assets/index-DWzv8ZoO.css +1 -0
- package/dist/gateway/static/root/assets/{index-XRbEWVyZ.js → index-DvKDT-RQ.js} +116 -116
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BGtrzFT6.js → keyboard-shortcuts-settings-mCs9cDgv.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-Cu80fCA0.js → local-app-workbench-page-B7AtlfWQ.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-Zsu8FnwP.js → local-apps-page-CIJE7jME.js} +1 -1
- package/dist/gateway/static/root/assets/{local-session-drafts-BjwlkAKA.js → local-session-drafts-fhip41-L.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-Djl2FW6_.js → locale-store-Jnhw2WMv.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-DlIhfEW_.js → logs-page-HawXUKF2.js} +2 -2
- package/dist/gateway/static/root/assets/management-settings-DByEh6rq.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-DyO7Q0Ms.js → markdown-view-B58RypQ4.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Ba1_QMmZ.js → media-plugins-B8BLxQgj.js} +1 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-CZjPT7xE.js +1 -0
- package/dist/gateway/static/root/assets/messages-DBvKzlCl.js +3 -0
- package/dist/gateway/static/root/assets/note-detail-panel-hQHB5fCs.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-BEusEk31.js +8 -0
- package/dist/gateway/static/root/assets/{page-context-capture-button-BqNWtf_f.js → page-context-capture-button-42bq8N6-.js} +1 -1
- package/dist/gateway/static/root/assets/personal-page-DPR5gzhf.js +1 -0
- package/dist/gateway/static/root/assets/plugin-details-dialog-D8dKKIY9.js +1 -0
- package/dist/gateway/static/root/assets/plugin-presentation-BrQpVvjC.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-kkbrbiVd.js → preview-open-alternatives-DKyLVLpX.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-Dheqo_4J.js → product-open-page-DcGH0AXN.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-content-B9Y6dIuh.js → product-preview-content-Ck6OzP09.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BHoQ10Eo.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-DYsq_OLJ.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BwR2CiR5.js → registry-api-BbUEMGcj.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CU3EChY0.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-api-C_VOMhLI.js → runtime-tools-api-D0xtCTXr.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BjyZGNP3.js → runtime-tools-settings-panel-Bfs5zKDg.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-DelMOLjg.js → schema-form-BbI2BuSU.js} +1 -1
- package/dist/gateway/static/root/assets/{session-api-DbNNQps9.js → session-api-CAKgrbgz.js} +1 -1
- package/dist/gateway/static/root/assets/{session-manager-DfVviLTK.js → session-manager-D_N7qha7.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CjB2GOTs.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-jbVx8gcF.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-DNWEDA71.js → settings-form-section-BfBBJlr-.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DJ27gC7J.js → settings-page-9yu4SN1j.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DhWB3feW.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Du4mumVM.js → share-preview-page-B6lQl5xb.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-UJGjdz3F.js +1 -0
- package/dist/gateway/static/root/assets/{skill-api-zOxHjU7m.js → skill-api-y2m3k_R4.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Bk9FqsVa.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-DLd4O-Fo.js +2 -0
- package/dist/gateway/static/root/assets/{style-DsnKw5jo.js → style-C2ptQg95.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-mz9hWo_H.js → system-settings-panel-DYzcLnVk.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-DLGtmHAH.js +2 -0
- package/dist/gateway/static/root/assets/{task-expandable-content-D3i_51Oc.js → task-expandable-content-HdEeV_0-.js} +1 -1
- package/dist/gateway/static/root/assets/{tracing-settings-page-aC-ziRbY.js → tracing-settings-page-DKQYmzFn.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-Ch2Veztk.js → tunnel-api-C2VY_HTy.js} +1 -1
- package/dist/gateway/static/root/assets/usage-page-CjzunQtj.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-BLW3t_OK.js → use-autosave-BElgnGMt.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-DsOGCDTR.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DulF6Cm4.js → voice-api-key-field-FVjX0qhn.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-Ceo_hqZC.js → voice-config-api-T3nM4buh.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-bBMZM8tN.js → work-discovery-overlay-B2S2NZuK.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CsxXS1WI.js → workflow-run-setup-panel-2Gq34KQk.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-CjeFD3mk.js +6 -0
- package/dist/gateway/static/root/assets/{xopc-cloud-account-card-wwIRBFCs.js → xopc-cloud-account-card-BZMIZxWg.js} +1 -1
- package/dist/gateway/static/root/index.html +15 -15
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +8 -0
- package/dist/src/agent/agent-manager.js +3 -3
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/codemode-extension.d.ts +1 -0
- package/dist/src/agent/embedded/codemode-extension.js +6 -1
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/embedded/run-turn.js +34 -2
- package/dist/src/agent/embedded/session-runner.js +1 -1
- package/dist/src/agent/external-tools/cliProvider.js +2 -2
- package/dist/src/agent/external-tools/composio-provider.js +2 -2
- package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
- package/dist/src/agent/mcp/config.d.ts +2 -0
- package/dist/src/agent/mcp/config.js +2 -2
- package/dist/src/agent/mcp/connection-setup.js +13 -1
- package/dist/src/agent/mcp/effective-server.d.ts +3 -0
- package/dist/src/agent/mcp/effective-server.js +27 -0
- package/dist/src/agent/mcp/native-mcp.d.ts +1 -1
- package/dist/src/agent/mcp/native-mcp.js +13 -4
- package/dist/src/agent/mcp/tool-catalog.js +2 -1
- package/dist/src/agent/service/process-direct-streaming.js +1 -1
- package/dist/src/agent/service.js +2 -2
- package/dist/src/agent/skills/index.d.ts +1 -0
- package/dist/src/agent/skills/index.js +7 -3
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.d.ts +1 -0
- package/dist/src/agent/skills/skill-manager.js +6 -1
- package/dist/src/agent/skills/skill-sources.d.ts +1 -0
- package/dist/src/agent/skills/skill-sources.js +4 -3
- package/dist/src/agent/skills/types.d.ts +1 -0
- package/dist/src/agent/tools/factory.js +1 -1
- package/dist/src/agent/tools/personal-read-tool.js +1 -1
- package/dist/src/agent/tools/xopc-use-tool.js +2 -2
- package/dist/src/agent/workspace-runtime/registry.js +7 -3
- package/dist/src/agent-catalog/capabilities.js +2 -2
- package/dist/src/automations/capabilities/drafts.js +1 -1
- package/dist/src/automations/service/action-executor.js +2 -2
- package/dist/src/bootstrap/application-state.js +1 -1
- package/dist/src/capabilities/runtime/dispatcher.js +1 -1
- package/dist/src/capabilities/runtime/product.js +1 -1
- package/dist/src/chat-commands/agent-edit.js +1 -1
- package/dist/src/cli/commands/agent.js +1 -1
- package/dist/src/cli/commands/agents.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-agent-plugin.js +92 -7
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension.js +1 -1
- package/dist/src/cli/commands/mcp.js +6 -4
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +1 -1
- package/dist/src/config/agent-model-intents.js +1 -1
- package/dist/src/config/agent-profile.js +2 -2
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.js +2 -2
- package/dist/src/extensions/agent-plugins/auth.d.ts +7 -1
- package/dist/src/extensions/agent-plugins/auth.js +53 -12
- package/dist/src/extensions/agent-plugins/branding.d.ts +12 -0
- package/dist/src/extensions/agent-plugins/branding.js +54 -0
- package/dist/src/extensions/agent-plugins/cli-authorization.d.ts +33 -0
- package/dist/src/extensions/agent-plugins/cli-authorization.js +203 -0
- package/dist/src/extensions/agent-plugins/connection-reuse.d.ts +10 -0
- package/dist/src/extensions/agent-plugins/connection-reuse.js +23 -0
- package/dist/src/extensions/agent-plugins/credentials.js +24 -1
- package/dist/src/extensions/agent-plugins/formats.d.ts +27 -0
- package/dist/src/extensions/agent-plugins/formats.js +208 -0
- package/dist/src/extensions/agent-plugins/inventory.d.ts +154 -2
- package/dist/src/extensions/agent-plugins/inventory.js +40 -5
- package/dist/src/extensions/agent-plugins/mcp-adapter.d.ts +2 -1
- package/dist/src/extensions/agent-plugins/mcp-adapter.js +42 -8
- package/dist/src/extensions/agent-plugins/mcp-format.d.ts +2 -0
- package/dist/src/extensions/agent-plugins/mcp-format.js +82 -0
- package/dist/src/extensions/agent-plugins/resources.d.ts +14 -0
- package/dist/src/extensions/agent-plugins/resources.js +112 -0
- package/dist/src/extensions/agent-plugins/setup-contract.d.ts +74 -0
- package/dist/src/extensions/agent-plugins/setup-contract.js +77 -0
- package/dist/src/extensions/agent-plugins/setup.d.ts +127 -0
- package/dist/src/extensions/agent-plugins/setup.js +496 -0
- package/dist/src/extensions/agent-plugins/skill-catalog.d.ts +14 -0
- package/dist/src/extensions/agent-plugins/skill-catalog.js +95 -0
- package/dist/src/extensions/agent-plugins/source-catalog.d.ts +21 -0
- package/dist/src/extensions/agent-plugins/source-catalog.js +175 -0
- package/dist/src/extensions/agent-plugins/sources.d.ts +1 -1
- package/dist/src/extensions/agent-plugins/sources.js +12 -3
- package/dist/src/extensions/agent-plugins/store.d.ts +33 -2
- package/dist/src/extensions/agent-plugins/store.js +175 -25
- package/dist/src/extensions/agent-plugins/user-config.d.ts +5 -0
- package/dist/src/extensions/agent-plugins/user-config.js +49 -0
- package/dist/src/extensions/agent-plugins/validation.d.ts +26 -1
- package/dist/src/extensions/agent-plugins/validation.js +143 -28
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/agent-plugins.js +121 -10
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/composer-history.js +22 -4
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
- package/dist/src/gateway/hono/routes/connectors.js +1 -1
- package/dist/src/gateway/hono/routes/context-sources.js +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +6 -4
- package/dist/src/gateway/hono/routes/notes.js +2 -2
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/session-input-handler.js +1 -1
- package/dist/src/gateway/hono/routes/tasks.js +1 -1
- package/dist/src/gateway/image-generation-setup.js +1 -1
- package/dist/src/gateway/lock.js +1 -1
- package/dist/src/gateway/service/marketplace-service.js +4 -2
- package/dist/src/gateway/service.js +8 -6
- package/dist/src/gateway/session-context-summary.js +1 -1
- package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
- package/dist/src/home-intelligence/host.js +2 -2
- package/dist/src/local-apps/service.js +1 -1
- package/dist/src/personal-agent/proactivity/service.js +1 -1
- package/dist/src/personal-agent/service.js +2 -2
- package/dist/src/providers/model-catalog-persistence.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/storage/sqlite/composer-input-history-repository.d.ts +4 -3
- package/dist/src/storage/sqlite/composer-input-history-repository.js +10 -8
- package/dist/src/storage/sqlite/migrations/257_session_composer_history.sql +11 -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/schema.js +1 -1
- package/dist/src/tasks/capabilities/read.js +2 -2
- package/dist/src/tasks/capabilities/write.js +1 -1
- package/dist/src/tasks/task-handoff-service.js +1 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +2 -2
- package/dist/src/tui/backends/embedded-backend.js +6 -6
- package/dist/src/tui/backends/gateway-realtime-backend.d.ts +2 -2
- package/dist/src/tui/backends/gateway-realtime-backend.js +7 -4
- package/dist/src/tui/composer-history.d.ts +14 -0
- package/dist/src/tui/composer-history.js +85 -0
- package/dist/src/tui/tui-backend.d.ts +4 -3
- package/dist/src/tui/tui.js +19 -46
- package/dist/src/voice/realtime/persona-context.js +1 -1
- package/package.json +12 -4
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-D8Q9Cpge.js +0 -1
- package/dist/gateway/static/root/assets/agent-plugin-dialog-C-UKhDkS.js +0 -1
- package/dist/gateway/static/root/assets/agents-DOv68iBN.js +0 -77
- package/dist/gateway/static/root/assets/apps-page-Da6Ar2U3.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-B9r27rPk.js +0 -6
- package/dist/gateway/static/root/assets/browser-automations-page-KLG8IXvl.js +0 -3
- package/dist/gateway/static/root/assets/browser-settings-page-Tcejw5fF.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-page-BJlw9rhA.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-kEvUR6Yu.js +0 -8
- package/dist/gateway/static/root/assets/channels-DRaE6_ub.js +0 -1
- package/dist/gateway/static/root/assets/computer-settings-page-B6JI2S1b.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-cDRZ8bqm.js +0 -1
- package/dist/gateway/static/root/assets/extension-page-BD4nZ9sf.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CxPIMrmn.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-DQ6-whg-.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-Da2CtQ7c.js +0 -1
- package/dist/gateway/static/root/assets/home-page-Cp4-sTfX.js +0 -2
- package/dist/gateway/static/root/assets/index-zIgp-ZTu.css +0 -1
- package/dist/gateway/static/root/assets/management-settings-CDV-xItG.js +0 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-CpK57Kgp.js +0 -1
- package/dist/gateway/static/root/assets/messages-DPxcWxfD.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-BXi6BrXd.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-ClR9R90o.js +0 -8
- package/dist/gateway/static/root/assets/personal-page-CSF-sn8w.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-l5dXxnSq.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-95Od8gLy.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DPEpPFax.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BN0nMm0w.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BvfEKyfy.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BWA_puDN.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-C0ixka9_.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-743oJIiS.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-DBYhEjP9.js +0 -2
- package/dist/gateway/static/root/assets/task-detail-page-Brp2wrEc.js +0 -2
- package/dist/gateway/static/root/assets/usage-page-KfKZ2a3t.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-BSsT8WjA.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-a-mfjQ2h.js +0 -6
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
|
|
4
|
+
import { pluginAuthorizations, pluginPermissionIssueSchema } from "./setup-contract.js";
|
|
5
|
+
import { preparePluginResources } from "./resources.js";
|
|
6
|
+
import { pluginName, pluginServerId } from "./validation.js";
|
|
7
|
+
import { AgentPluginStore } from "./store.js";
|
|
8
|
+
import { connectionFingerprint, matchingReusableConnection } from "./connection-reuse.js";
|
|
9
|
+
import { createNativeMcpCredentials } from "../../agent/mcp/credential-store.js";
|
|
10
|
+
import { readPluginAuthBinding, savePluginAuthBinding, savePluginOAuthReference } from "./auth.js";
|
|
11
|
+
import { pluginConfigMissing, readPluginUserConfig, savePluginUserConfig } from "./user-config.js";
|
|
12
|
+
import { materializePluginServers } from "./mcp-adapter.js";
|
|
13
|
+
import { getNativePiAgentDir } from "../../agent/mcp/native-mcp.js";
|
|
14
|
+
import { cancelMcpAuthorization, getMcpAuthorization, probeMcpConnection, startMcpAuthorization, submitMcpRedirect } from "../../agent/mcp/connection-setup.js";
|
|
15
|
+
import { cancelPluginCliAuthorizations, getPluginCliAuthorization, inspectPluginCliAuthorization, startPluginCliAuthorization } from "./cli-authorization.js";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
18
|
+
import { randomUUID } from "node:crypto";
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
import lockfile from "proper-lockfile";
|
|
21
|
+
//#region src/extensions/agent-plugins/setup.ts
|
|
22
|
+
init_logger();
|
|
23
|
+
init_write_file_atomic();
|
|
24
|
+
const connection = z.object({
|
|
25
|
+
name: z.string(),
|
|
26
|
+
state: z.enum([
|
|
27
|
+
"pending",
|
|
28
|
+
"connected",
|
|
29
|
+
"oauth_required",
|
|
30
|
+
"token_required",
|
|
31
|
+
"error",
|
|
32
|
+
"skipped"
|
|
33
|
+
]),
|
|
34
|
+
toolCount: z.number().optional(),
|
|
35
|
+
authorizationId: z.string().optional()
|
|
36
|
+
});
|
|
37
|
+
const schema = z.object({
|
|
38
|
+
id: z.string().uuid(),
|
|
39
|
+
pluginId: pluginName,
|
|
40
|
+
owner: z.string(),
|
|
41
|
+
packageRevision: z.string().uuid(),
|
|
42
|
+
revision: z.number().int(),
|
|
43
|
+
state: z.enum([
|
|
44
|
+
"pending",
|
|
45
|
+
"running",
|
|
46
|
+
"action_required",
|
|
47
|
+
"completed",
|
|
48
|
+
"cancelled",
|
|
49
|
+
"interrupted",
|
|
50
|
+
"failed"
|
|
51
|
+
]),
|
|
52
|
+
resources: z.enum([
|
|
53
|
+
"pending",
|
|
54
|
+
"running",
|
|
55
|
+
"ready",
|
|
56
|
+
"error"
|
|
57
|
+
]),
|
|
58
|
+
connections: z.array(connection),
|
|
59
|
+
installed: z.boolean().default(false),
|
|
60
|
+
deferred: z.boolean().default(false),
|
|
61
|
+
authorizations: z.array(z.object({
|
|
62
|
+
id: z.string(),
|
|
63
|
+
state: z.enum([
|
|
64
|
+
"pending",
|
|
65
|
+
"connected",
|
|
66
|
+
"skipped",
|
|
67
|
+
"error"
|
|
68
|
+
]),
|
|
69
|
+
issues: z.array(pluginPermissionIssueSchema).max(20).default([]),
|
|
70
|
+
method: z.string().optional(),
|
|
71
|
+
attemptId: z.string().optional()
|
|
72
|
+
})).default([]),
|
|
73
|
+
operations: z.array(z.object({
|
|
74
|
+
key: z.string().uuid(),
|
|
75
|
+
action: z.string()
|
|
76
|
+
})).max(100).default([]),
|
|
77
|
+
missingConfig: z.array(z.string()).default([]),
|
|
78
|
+
partial: z.boolean(),
|
|
79
|
+
updatedAt: z.string(),
|
|
80
|
+
error: z.string().optional()
|
|
81
|
+
});
|
|
82
|
+
const actionRevision = {
|
|
83
|
+
expectedRevision: z.number().int(),
|
|
84
|
+
idempotencyKey: z.string().uuid().optional()
|
|
85
|
+
};
|
|
86
|
+
const setupActionSchema = z.discriminatedUnion("action", [
|
|
87
|
+
z.strictObject({
|
|
88
|
+
action: z.literal("prepare"),
|
|
89
|
+
...actionRevision
|
|
90
|
+
}),
|
|
91
|
+
z.strictObject({
|
|
92
|
+
action: z.literal("reuse"),
|
|
93
|
+
...actionRevision,
|
|
94
|
+
server: z.string(),
|
|
95
|
+
sourceServerId: z.string()
|
|
96
|
+
}),
|
|
97
|
+
z.strictObject({
|
|
98
|
+
action: z.literal("authorize"),
|
|
99
|
+
...actionRevision,
|
|
100
|
+
server: z.string(),
|
|
101
|
+
method: z.string().optional()
|
|
102
|
+
}),
|
|
103
|
+
z.strictObject({
|
|
104
|
+
action: z.literal("configure"),
|
|
105
|
+
...actionRevision,
|
|
106
|
+
values: z.record(z.string(), z.unknown()),
|
|
107
|
+
authorization: z.string().optional(),
|
|
108
|
+
method: z.string().optional()
|
|
109
|
+
}),
|
|
110
|
+
z.strictObject({
|
|
111
|
+
action: z.literal("complete"),
|
|
112
|
+
...actionRevision,
|
|
113
|
+
workspacePaths: z.array(z.string().min(1)).max(100).nullable().optional(),
|
|
114
|
+
allowPartial: z.boolean().default(false)
|
|
115
|
+
}),
|
|
116
|
+
z.strictObject({
|
|
117
|
+
action: z.literal("defer"),
|
|
118
|
+
...actionRevision
|
|
119
|
+
}),
|
|
120
|
+
z.strictObject({
|
|
121
|
+
action: z.literal("cancel"),
|
|
122
|
+
...actionRevision
|
|
123
|
+
})
|
|
124
|
+
]);
|
|
125
|
+
const log = createLogger("PluginSetup");
|
|
126
|
+
const running = /* @__PURE__ */ new Map();
|
|
127
|
+
var PluginSetupService = class {
|
|
128
|
+
constructor(store = new AgentPluginStore()) {
|
|
129
|
+
this.store = store;
|
|
130
|
+
}
|
|
131
|
+
path(id) {
|
|
132
|
+
return join(this.store.stateDir, "plugin-setup", `${pluginName.parse(id)}.json`);
|
|
133
|
+
}
|
|
134
|
+
key(id) {
|
|
135
|
+
return this.path(id);
|
|
136
|
+
}
|
|
137
|
+
write(job) {
|
|
138
|
+
job.revision++;
|
|
139
|
+
job.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
140
|
+
writeTextAtomicSync(this.path(job.pluginId), JSON.stringify(schema.parse(job)));
|
|
141
|
+
}
|
|
142
|
+
get(id, owner) {
|
|
143
|
+
if (!existsSync(this.path(id))) return;
|
|
144
|
+
const job = schema.parse(JSON.parse(readFileSync(this.path(id), "utf8")));
|
|
145
|
+
if (job.owner !== owner) throw new Error("Setup belongs to another principal");
|
|
146
|
+
if (job.state === "running" && !running.has(this.key(id)) && !lockfile.checkSync(this.path(id), { realpath: false })) {
|
|
147
|
+
job.state = "interrupted";
|
|
148
|
+
job.error = "Preparation was interrupted. Retry to continue.";
|
|
149
|
+
this.write(job);
|
|
150
|
+
}
|
|
151
|
+
return job;
|
|
152
|
+
}
|
|
153
|
+
create(id, owner) {
|
|
154
|
+
const plugin = this.store.pending(id) ?? this.store.get(id);
|
|
155
|
+
if (!plugin || plugin.readiness === "blocked") throw new Error("Plugin unavailable");
|
|
156
|
+
const previous = this.get(id, owner);
|
|
157
|
+
if (previous?.packageRevision === plugin.receipt.revision && previous.state !== "cancelled") return previous;
|
|
158
|
+
if (running.has(this.key(id)) || lockfile.checkSync(this.path(id), { realpath: false })) throw new Error("Preparation is already running");
|
|
159
|
+
const job = {
|
|
160
|
+
id: randomUUID(),
|
|
161
|
+
pluginId: id,
|
|
162
|
+
owner,
|
|
163
|
+
packageRevision: plugin.receipt.revision,
|
|
164
|
+
revision: 0,
|
|
165
|
+
state: "pending",
|
|
166
|
+
resources: "pending",
|
|
167
|
+
connections: Object.keys(plugin.servers).map((name) => ({
|
|
168
|
+
name,
|
|
169
|
+
state: "pending"
|
|
170
|
+
})),
|
|
171
|
+
installed: false,
|
|
172
|
+
deferred: false,
|
|
173
|
+
authorizations: pluginAuthorizations(plugin.manifest).map((value) => ({
|
|
174
|
+
id: value.id,
|
|
175
|
+
state: "pending",
|
|
176
|
+
issues: []
|
|
177
|
+
})),
|
|
178
|
+
operations: [],
|
|
179
|
+
missingConfig: pluginConfigMissing(this.store, plugin),
|
|
180
|
+
partial: plugin.diagnostics.length > 0,
|
|
181
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
182
|
+
};
|
|
183
|
+
this.write(job);
|
|
184
|
+
return job;
|
|
185
|
+
}
|
|
186
|
+
invalidateConnection(id, owner, name) {
|
|
187
|
+
const job = this.get(id, owner);
|
|
188
|
+
if (!job) return;
|
|
189
|
+
running.get(this.key(id))?.abort();
|
|
190
|
+
const server = job.connections.find((value) => value.name === name);
|
|
191
|
+
if (server) {
|
|
192
|
+
if (server.authorizationId) cancelMcpAuthorization(server.authorizationId, owner);
|
|
193
|
+
server.state = "pending";
|
|
194
|
+
delete server.authorizationId;
|
|
195
|
+
}
|
|
196
|
+
job.state = "action_required";
|
|
197
|
+
this.write(job);
|
|
198
|
+
}
|
|
199
|
+
async reusableConnections(id, owner, config) {
|
|
200
|
+
if (!this.get(id, owner)) return {};
|
|
201
|
+
const plugin = this.store.pending(id) ?? this.store.get(id);
|
|
202
|
+
if (!plugin) return {};
|
|
203
|
+
getNativePiAgentDir();
|
|
204
|
+
const credentials = await createNativeMcpCredentials();
|
|
205
|
+
const result = {};
|
|
206
|
+
for (const [name, target] of Object.entries(plugin.servers)) {
|
|
207
|
+
result[name] = [];
|
|
208
|
+
for (const [sourceId, source] of Object.entries(config.mcp?.servers ?? {})) {
|
|
209
|
+
if (!matchingReusableConnection(target, source) || !source.url || !source.xopcOAuthCredentialId) continue;
|
|
210
|
+
if (await credentials.tokens(source.xopcOAuthCredentialId, source.url)) result[name].push({
|
|
211
|
+
id: sourceId,
|
|
212
|
+
name: source.displayName ?? sourceId
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return result;
|
|
217
|
+
}
|
|
218
|
+
async authorization(id, owner, server, config) {
|
|
219
|
+
const job = this.get(id, owner);
|
|
220
|
+
if (!job) throw new Error("Setup not found");
|
|
221
|
+
const declared = pluginAuthorizations((this.store.pending(id) ?? this.store.get(id)).manifest).find((value) => value.id === server);
|
|
222
|
+
const selected = job.authorizations.find((value) => value.id === server);
|
|
223
|
+
const method = declared?.methods.find((value) => value.id === selected?.method);
|
|
224
|
+
if (method?.type === "cli") return selected?.attemptId ? getPluginCliAuthorization(selected.attemptId, owner, job.packageRevision) : void 0;
|
|
225
|
+
const target = job.connections.find((c) => c.name === (method?.type === "oauth" ? method.server : server));
|
|
226
|
+
if (!target?.authorizationId) return void 0;
|
|
227
|
+
const effective = this.config(id, job.packageRevision, config);
|
|
228
|
+
return getMcpAuthorization(target.authorizationId, owner, effective);
|
|
229
|
+
}
|
|
230
|
+
redirect(id, owner, server, url, config) {
|
|
231
|
+
const job = this.get(id, owner);
|
|
232
|
+
const declaration = pluginAuthorizations((this.store.pending(id) ?? this.store.get(id)).manifest).find((value) => value.id === server);
|
|
233
|
+
const selected = job?.authorizations.find((value) => value.id === server);
|
|
234
|
+
const method = declaration?.methods.find((value) => value.id === selected?.method);
|
|
235
|
+
const attempt = job?.connections.find((c) => c.name === (method?.type === "oauth" ? method.server : server))?.authorizationId;
|
|
236
|
+
return !!job && !!attempt && submitMcpRedirect(attempt, owner, url, this.config(id, job.packageRevision, config));
|
|
237
|
+
}
|
|
238
|
+
config(id, revision, config) {
|
|
239
|
+
const plugin = this.store.pending(id) ?? this.store.get(id);
|
|
240
|
+
if (!plugin || plugin.receipt.revision !== revision || plugin.readiness === "blocked") throw new Error("Plugin revision changed; restart setup");
|
|
241
|
+
const servers = materializePluginServers(plugin, this.store, [], true);
|
|
242
|
+
return {
|
|
243
|
+
...config,
|
|
244
|
+
mcp: {
|
|
245
|
+
...config.mcp,
|
|
246
|
+
servers: {
|
|
247
|
+
...config.mcp?.servers,
|
|
248
|
+
...servers
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
startPrepare(id, owner, revision, config, workspace, idempotencyKey) {
|
|
254
|
+
const current = this.get(id, owner);
|
|
255
|
+
if (idempotencyKey && current?.operations.some((op) => op.key === idempotencyKey && op.action === "prepare")) return current;
|
|
256
|
+
if (!current || current.revision !== revision) throw new Error("Setup changed. Refresh and retry.");
|
|
257
|
+
if (current.state === "running") return current;
|
|
258
|
+
if (lockfile.checkSync(this.path(id), { realpath: false })) throw new Error("Preparation is already running");
|
|
259
|
+
this.act(id, owner, {
|
|
260
|
+
action: "prepare",
|
|
261
|
+
expectedRevision: revision,
|
|
262
|
+
idempotencyKey
|
|
263
|
+
}, config, workspace).catch(() => {
|
|
264
|
+
log.warn({ pluginId: id }, "Plugin preparation could not continue");
|
|
265
|
+
});
|
|
266
|
+
return this.get(id, owner);
|
|
267
|
+
}
|
|
268
|
+
async act(id, owner, input, config, workspace) {
|
|
269
|
+
const current = this.get(id, owner);
|
|
270
|
+
const previous = input.idempotencyKey && current?.operations.find((op) => op.key === input.idempotencyKey);
|
|
271
|
+
if (previous) {
|
|
272
|
+
if (previous.action !== input.action) throw new Error("Idempotency key belongs to another action");
|
|
273
|
+
return current;
|
|
274
|
+
}
|
|
275
|
+
const remember = (job) => {
|
|
276
|
+
if (input.idempotencyKey && (job.state !== "cancelled" || input.action === "cancel")) {
|
|
277
|
+
job.operations = [...job.operations, {
|
|
278
|
+
key: input.idempotencyKey,
|
|
279
|
+
action: input.action
|
|
280
|
+
}].slice(-100);
|
|
281
|
+
this.write(job);
|
|
282
|
+
}
|
|
283
|
+
return job;
|
|
284
|
+
};
|
|
285
|
+
if (input.action === "cancel") return remember(await this.perform(id, owner, input, config, workspace));
|
|
286
|
+
const release = lockfile.lockSync(this.path(id), { realpath: false });
|
|
287
|
+
try {
|
|
288
|
+
return remember(await this.perform(id, owner, input, config, workspace));
|
|
289
|
+
} finally {
|
|
290
|
+
release();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
async perform(id, owner, input, config, workspace) {
|
|
294
|
+
const job = this.get(id, owner);
|
|
295
|
+
if (!job) throw new Error("Setup not found");
|
|
296
|
+
if (job.revision !== input.expectedRevision) throw new Error("Setup changed. Refresh and retry.");
|
|
297
|
+
if (input.action === "cancel") {
|
|
298
|
+
running.get(this.key(id))?.abort();
|
|
299
|
+
cancelPluginCliAuthorizations(id, owner);
|
|
300
|
+
for (const server of job.connections) if (server.authorizationId) cancelMcpAuthorization(server.authorizationId, owner);
|
|
301
|
+
job.state = "cancelled";
|
|
302
|
+
this.write(job);
|
|
303
|
+
this.store.discardPending(id);
|
|
304
|
+
return job;
|
|
305
|
+
}
|
|
306
|
+
if (running.has(this.key(id))) throw new Error("Preparation is already running");
|
|
307
|
+
if (job.state === "cancelled") throw new Error("Restart setup before continuing");
|
|
308
|
+
const effective = this.config(id, job.packageRevision, config);
|
|
309
|
+
const plugin = this.store.pending(id) ?? this.store.get(id);
|
|
310
|
+
const declarations = pluginAuthorizations(plugin.manifest);
|
|
311
|
+
if (input.action === "configure") {
|
|
312
|
+
const controller = new AbortController();
|
|
313
|
+
running.set(this.key(id), controller);
|
|
314
|
+
try {
|
|
315
|
+
if (input.authorization || input.method) {
|
|
316
|
+
const declaration = declarations.find((value) => value.id === input.authorization);
|
|
317
|
+
const method = declaration?.methods.find((value) => value.id === input.method);
|
|
318
|
+
if (!method || !("fields" in method) || Object.keys(input.values).some((key) => !method.fields.includes(key))) throw new Error("Invalid credential form");
|
|
319
|
+
const saved = readPluginUserConfig(this.store, id, plugin.receipt.revision);
|
|
320
|
+
if (method.fields.some((key) => input.values[key] === void 0 && saved[key] === void 0 || typeof input.values[key] === "string" && !input.values[key].trim())) throw new Error("Complete the required credential fields");
|
|
321
|
+
const target = job.authorizations.find((value) => value.id === declaration.id);
|
|
322
|
+
target.method = method.id;
|
|
323
|
+
target.state = "pending";
|
|
324
|
+
delete target.attemptId;
|
|
325
|
+
}
|
|
326
|
+
cancelPluginCliAuthorizations(id, owner);
|
|
327
|
+
await savePluginUserConfig(this.store, plugin, input.values);
|
|
328
|
+
controller.signal.throwIfAborted();
|
|
329
|
+
this.config(id, job.packageRevision, config);
|
|
330
|
+
for (const server of job.connections) {
|
|
331
|
+
if (input.authorization && !declarations.find((value) => value.id === input.authorization)?.servers.includes(server.name)) continue;
|
|
332
|
+
if (server.authorizationId) cancelMcpAuthorization(server.authorizationId, owner);
|
|
333
|
+
server.state = "pending";
|
|
334
|
+
delete server.authorizationId;
|
|
335
|
+
}
|
|
336
|
+
job.missingConfig = pluginConfigMissing(this.store, plugin);
|
|
337
|
+
job.state = "action_required";
|
|
338
|
+
this.write(job);
|
|
339
|
+
return job;
|
|
340
|
+
} finally {
|
|
341
|
+
running.delete(this.key(id));
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (input.action === "reuse") {
|
|
345
|
+
const source = config.mcp?.servers?.[input.sourceServerId];
|
|
346
|
+
const candidates = await this.reusableConnections(id, owner, config);
|
|
347
|
+
if (!source?.xopcOAuthCredentialId || !candidates[input.server]?.some((value) => value.id === input.sourceServerId)) throw new Error("This connection is unavailable or has different endpoint or OAuth scopes");
|
|
348
|
+
if (this.get(id, owner)?.revision !== job.revision) throw new Error("Setup changed. Refresh and retry.");
|
|
349
|
+
savePluginOAuthReference(this.store, id, input.server, {
|
|
350
|
+
sourceServerId: input.sourceServerId,
|
|
351
|
+
credentialId: source.xopcOAuthCredentialId,
|
|
352
|
+
fingerprint: connectionFingerprint(source)
|
|
353
|
+
});
|
|
354
|
+
const server = job.connections.find((value) => value.name === input.server);
|
|
355
|
+
if (server.authorizationId) cancelMcpAuthorization(server.authorizationId, owner);
|
|
356
|
+
server.state = "pending";
|
|
357
|
+
delete server.authorizationId;
|
|
358
|
+
job.state = "action_required";
|
|
359
|
+
this.write(job);
|
|
360
|
+
return job;
|
|
361
|
+
}
|
|
362
|
+
if (input.action === "authorize") {
|
|
363
|
+
const declaration = declarations.find((value) => value.id === input.server);
|
|
364
|
+
const method = declaration?.methods.find((value) => value.id === input.method);
|
|
365
|
+
if (declaration && !method) throw new Error("Choose an authorization method");
|
|
366
|
+
if (method?.type === "form") throw new Error("Complete this method using its credential form");
|
|
367
|
+
if (declaration && method) {
|
|
368
|
+
if (job.resources !== "ready") throw new Error("Prepare resources before signing in");
|
|
369
|
+
const target = job.authorizations.find((value) => value.id === declaration.id);
|
|
370
|
+
target.method = method.id;
|
|
371
|
+
target.state = "pending";
|
|
372
|
+
for (const server of job.connections) if (declaration.servers.includes(server.name)) {
|
|
373
|
+
if (server.authorizationId) cancelMcpAuthorization(server.authorizationId, owner);
|
|
374
|
+
server.state = "pending";
|
|
375
|
+
delete server.authorizationId;
|
|
376
|
+
}
|
|
377
|
+
if (method.type === "cli") {
|
|
378
|
+
target.attemptId = startPluginCliAuthorization(this.store, plugin, declaration.id, method, owner).id;
|
|
379
|
+
job.state = "action_required";
|
|
380
|
+
this.write(job);
|
|
381
|
+
return job;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
const server = job.connections.find((c) => c.name === (method?.type === "oauth" ? method.server : input.server));
|
|
385
|
+
if (!server) throw new Error("Unknown setup connection");
|
|
386
|
+
const target = plugin.servers[server.name];
|
|
387
|
+
if (target && readPluginAuthBinding(this.store, id, server.name, target, plugin.receipt.revision)?.oauthReference) await savePluginAuthBinding(this.store, id, server.name, { mode: "auto" });
|
|
388
|
+
if (this.get(id, owner)?.revision !== job.revision) throw new Error("Setup changed. Refresh and retry.");
|
|
389
|
+
server.authorizationId = startMcpAuthorization(this.config(id, job.packageRevision, config), workspace, pluginServerId(id, server.name), owner, { authorizationScope: `${job.id}:${server.name}` }).id;
|
|
390
|
+
job.state = "action_required";
|
|
391
|
+
this.write(job);
|
|
392
|
+
return job;
|
|
393
|
+
}
|
|
394
|
+
if (input.action === "complete" || input.action === "defer") {
|
|
395
|
+
const deferred = input.action === "defer";
|
|
396
|
+
if (job.resources !== "ready" || !deferred && pluginConfigMissing(this.store, plugin).length) throw new Error("Prepare resources and configuration first");
|
|
397
|
+
const partial = plugin.diagnostics.length > 0 || job.connections.some((c) => c.state !== "connected") || job.authorizations.some((value) => value.state !== "connected") || pluginConfigMissing(this.store, plugin).length > 0;
|
|
398
|
+
if (partial && !deferred && !("allowPartial" in input && input.allowPartial)) throw new Error("Some capabilities are unavailable. Review before enabling partially.");
|
|
399
|
+
if (plugin.layout?.compatibility.some((item) => item.component === "hooks")) throw new Error("Lifecycle hooks are not supported; keep this plugin installed and disabled until a compatible adapter is available");
|
|
400
|
+
this.store.commitPending(id);
|
|
401
|
+
this.store.setWorkspaceScope(id, "workspacePaths" in input ? input.workspacePaths : void 0);
|
|
402
|
+
this.store.setEnabled(id, true);
|
|
403
|
+
if (deferred) {
|
|
404
|
+
delete job.error;
|
|
405
|
+
cancelPluginCliAuthorizations(id, owner);
|
|
406
|
+
for (const server of job.connections) if (server.authorizationId && server.state !== "connected") cancelMcpAuthorization(server.authorizationId, owner);
|
|
407
|
+
}
|
|
408
|
+
job.installed = true;
|
|
409
|
+
job.deferred = deferred && partial;
|
|
410
|
+
job.partial = partial;
|
|
411
|
+
job.state = "completed";
|
|
412
|
+
this.write(job);
|
|
413
|
+
return job;
|
|
414
|
+
}
|
|
415
|
+
const controller = new AbortController();
|
|
416
|
+
running.set(this.key(id), controller);
|
|
417
|
+
const cancellationPoll = setInterval(() => {
|
|
418
|
+
try {
|
|
419
|
+
const current = this.get(id, owner);
|
|
420
|
+
if (!current || current.id !== job.id || current.revision !== job.revision || current.state === "cancelled" || !this.store.receipt(id)) controller.abort();
|
|
421
|
+
} catch {
|
|
422
|
+
controller.abort();
|
|
423
|
+
}
|
|
424
|
+
}, 500);
|
|
425
|
+
cancellationPoll.unref();
|
|
426
|
+
job.state = "running";
|
|
427
|
+
job.resources = "running";
|
|
428
|
+
delete job.error;
|
|
429
|
+
this.write(job);
|
|
430
|
+
try {
|
|
431
|
+
await preparePluginResources(this.store, plugin, controller.signal);
|
|
432
|
+
job.resources = "ready";
|
|
433
|
+
job.missingConfig = pluginConfigMissing(this.store, plugin);
|
|
434
|
+
if (job.missingConfig.length) {
|
|
435
|
+
job.state = "action_required";
|
|
436
|
+
job.error = "Complete the required configuration fields.";
|
|
437
|
+
} else {
|
|
438
|
+
for (const target of job.authorizations) {
|
|
439
|
+
const method = declarations.find((value) => value.id === target.id).methods.find((value) => value.id === target.method);
|
|
440
|
+
if (method?.type === "cli") {
|
|
441
|
+
const check = await inspectPluginCliAuthorization(this.store, plugin, target.id, method, controller.signal);
|
|
442
|
+
target.state = check.authenticated ? "connected" : "pending";
|
|
443
|
+
target.issues = check.issues;
|
|
444
|
+
} else if (method?.type === "form") {
|
|
445
|
+
const values = readPluginUserConfig(this.store, id, plugin.receipt.revision);
|
|
446
|
+
target.state = method.fields.every((key) => values[key] !== void 0 && values[key] !== "") ? "connected" : "pending";
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
for (const server of job.connections) {
|
|
450
|
+
controller.signal.throwIfAborted();
|
|
451
|
+
if (declarations.filter((value) => value.servers.includes(server.name)).some((gate) => {
|
|
452
|
+
const target = job.authorizations.find((value) => value.id === gate.id);
|
|
453
|
+
const method = gate.methods.find((value) => value.id === target.method);
|
|
454
|
+
return !method || method.type !== "oauth" && target.state !== "connected";
|
|
455
|
+
})) {
|
|
456
|
+
server.state = "skipped";
|
|
457
|
+
delete server.toolCount;
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
const result = await probeMcpConnection(effective, workspace, pluginServerId(id, server.name), { signal: controller.signal });
|
|
461
|
+
controller.signal.throwIfAborted();
|
|
462
|
+
server.state = result.state;
|
|
463
|
+
server.toolCount = result.toolCount;
|
|
464
|
+
const persisted = this.get(id, owner);
|
|
465
|
+
if (!persisted || persisted.id !== job.id || persisted.revision !== job.revision || persisted.state === "cancelled" || !this.store.receipt(id)) throw new Error("Setup changed");
|
|
466
|
+
this.config(id, job.packageRevision, config);
|
|
467
|
+
this.write(job);
|
|
468
|
+
}
|
|
469
|
+
for (const target of job.authorizations) target.state = declarations.find((value) => value.id === target.id).servers.every((name) => job.connections.find((value) => value.name === name)?.state === "connected") ? "connected" : "pending";
|
|
470
|
+
job.partial = plugin.diagnostics.length > 0;
|
|
471
|
+
if (job.connections.some((value) => value.state === "error")) job.error = "Connection verification failed. Check the credentials or login status and try again.";
|
|
472
|
+
job.state = "action_required";
|
|
473
|
+
}
|
|
474
|
+
this.config(id, job.packageRevision, config);
|
|
475
|
+
controller.signal.throwIfAborted();
|
|
476
|
+
if (this.get(id, owner)?.id !== job.id || this.get(id, owner)?.state === "cancelled") throw new Error("Setup changed");
|
|
477
|
+
this.write(job);
|
|
478
|
+
} catch {
|
|
479
|
+
const current = this.get(id, owner);
|
|
480
|
+
if (!controller.signal.aborted && current?.id === job.id && current.revision === job.revision && current.state !== "cancelled" && (this.store.pending(id) ?? this.store.get(id))?.receipt.revision === job.packageRevision) {
|
|
481
|
+
job.state = "failed";
|
|
482
|
+
if (job.resources !== "ready") job.resources = "error";
|
|
483
|
+
job.error = "Preparation failed. Retry after checking resources and connections.";
|
|
484
|
+
this.write(job);
|
|
485
|
+
}
|
|
486
|
+
} finally {
|
|
487
|
+
clearInterval(cancellationPoll);
|
|
488
|
+
running.delete(this.key(id));
|
|
489
|
+
}
|
|
490
|
+
const latest = this.get(id, owner);
|
|
491
|
+
if (!latest) throw new Error("Setup was removed");
|
|
492
|
+
return latest;
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
//#endregion
|
|
496
|
+
export { PluginSetupService, setupActionSchema };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SkillCatalogEntry } from '../../agent/agent-manager.js';
|
|
2
|
+
import { AgentPluginStore } from './store.js';
|
|
3
|
+
export declare function pluginSkillName(plugin: ReturnType<AgentPluginStore['list']>[number], name: string): string;
|
|
4
|
+
/** Browse installed content without enabling it in the Agent runtime. */
|
|
5
|
+
export declare function withPluginSkillCatalog(catalog: SkillCatalogEntry[], store?: AgentPluginStore): SkillCatalogEntry[];
|
|
6
|
+
export declare function pluginSkillPreview(name: string, store?: AgentPluginStore): {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
bodyMarkdown: string;
|
|
10
|
+
disableModelInvocation: boolean;
|
|
11
|
+
metadata: import("../../agent/skills/types.js").SkillMetadata;
|
|
12
|
+
toolConditions?: import("../../agent/skills/types.js").SkillToolConditions;
|
|
13
|
+
requiredEnvVarNames?: string[];
|
|
14
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
2
|
+
import { createSkillConfigManager } from "../../agent/skills/config.js";
|
|
3
|
+
import { parseSkillLocalizations } from "../../agent/skills/parse-skill-metadata.js";
|
|
4
|
+
import { containedPath } from "./validation.js";
|
|
5
|
+
import { AgentPluginStore } from "./store.js";
|
|
6
|
+
import { buildSkillMarkdownPreviewFromRaw } from "../../agent/skills/skill-markdown-preview-from-raw.js";
|
|
7
|
+
import { agentPluginInventoryRow } from "./inventory.js";
|
|
8
|
+
import { basename, dirname } from "node:path";
|
|
9
|
+
import { readFileSync } from "node:fs";
|
|
10
|
+
//#region src/extensions/agent-plugins/skill-catalog.ts
|
|
11
|
+
function pluginSkillName(plugin, name) {
|
|
12
|
+
return plugin.layout?.dialect !== "portable" ? `${plugin.id}.${name}` : name;
|
|
13
|
+
}
|
|
14
|
+
/** Browse installed content without enabling it in the Agent runtime. */
|
|
15
|
+
function withPluginSkillCatalog(catalog, store = new AgentPluginStore()) {
|
|
16
|
+
const rows = [...catalog];
|
|
17
|
+
const config = createSkillConfigManager(store.stateDir).load();
|
|
18
|
+
for (const plugin of store.list()) {
|
|
19
|
+
const inventory = agentPluginInventoryRow(plugin, store);
|
|
20
|
+
const owner = {
|
|
21
|
+
id: plugin.id,
|
|
22
|
+
name: plugin.manifest.name,
|
|
23
|
+
title: inventory.setup.authorizations.length === 1 ? inventory.setup.authorizations[0].title : plugin.manifest.name,
|
|
24
|
+
authorizationStatus: inventory.authorizationStatus,
|
|
25
|
+
active: inventory.active,
|
|
26
|
+
readiness: plugin.readiness
|
|
27
|
+
};
|
|
28
|
+
for (const skill of plugin.skills) {
|
|
29
|
+
const name = pluginSkillName(plugin, skill.name);
|
|
30
|
+
const index = rows.findIndex((row) => row.origin === `plugin:${plugin.id}` && row.name === name);
|
|
31
|
+
try {
|
|
32
|
+
const raw = readFileSync(containedPath(plugin.rootDir, skill.filePath), "utf8");
|
|
33
|
+
const preview = buildSkillMarkdownPreviewFromRaw(raw, {
|
|
34
|
+
name,
|
|
35
|
+
description: ""
|
|
36
|
+
});
|
|
37
|
+
const { frontmatter } = parseFrontmatter(raw);
|
|
38
|
+
const fm = frontmatter;
|
|
39
|
+
const localizations = parseSkillLocalizations(fm).localizations ?? {
|
|
40
|
+
en: {
|
|
41
|
+
displayName: skill.name,
|
|
42
|
+
description: preview.description
|
|
43
|
+
},
|
|
44
|
+
"zh-CN": {
|
|
45
|
+
displayName: typeof fm.displayName === "string" ? fm.displayName : skill.name,
|
|
46
|
+
description: typeof fm.displayDescription === "string" ? fm.displayDescription : preview.description
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
if (index >= 0) {
|
|
50
|
+
rows[index] = {
|
|
51
|
+
...rows[index],
|
|
52
|
+
localizations,
|
|
53
|
+
plugin: owner
|
|
54
|
+
};
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
rows.push({
|
|
58
|
+
localizations,
|
|
59
|
+
directoryId: basename(dirname(skill.filePath)),
|
|
60
|
+
name,
|
|
61
|
+
description: preview.description,
|
|
62
|
+
source: "global",
|
|
63
|
+
origin: `plugin:${plugin.id}`,
|
|
64
|
+
path: dirname(skill.filePath),
|
|
65
|
+
managed: false,
|
|
66
|
+
writable: false,
|
|
67
|
+
enabled: config.entries?.[name]?.enabled !== false,
|
|
68
|
+
disableModelInvocation: preview.disableModelInvocation,
|
|
69
|
+
plugin: owner
|
|
70
|
+
});
|
|
71
|
+
} catch {}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return rows;
|
|
75
|
+
}
|
|
76
|
+
function pluginSkillPreview(name, store = new AgentPluginStore()) {
|
|
77
|
+
for (const plugin of store.list()) {
|
|
78
|
+
const skill = plugin.skills.find((skill) => pluginSkillName(plugin, skill.name) === name);
|
|
79
|
+
if (!skill) continue;
|
|
80
|
+
try {
|
|
81
|
+
return {
|
|
82
|
+
...buildSkillMarkdownPreviewFromRaw(readFileSync(containedPath(plugin.rootDir, skill.filePath), "utf8"), {
|
|
83
|
+
name,
|
|
84
|
+
description: ""
|
|
85
|
+
}),
|
|
86
|
+
name
|
|
87
|
+
};
|
|
88
|
+
} catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
export { pluginSkillName, pluginSkillPreview, withPluginSkillCatalog };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface PluginCandidate {
|
|
2
|
+
name: string;
|
|
3
|
+
source: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class PluginSourceRedirect extends Error {
|
|
7
|
+
readonly source: string;
|
|
8
|
+
constructor(source: string);
|
|
9
|
+
}
|
|
10
|
+
export declare class PluginSelectionRequired extends Error {
|
|
11
|
+
readonly candidates: PluginCandidate[];
|
|
12
|
+
constructor(candidates: PluginCandidate[]);
|
|
13
|
+
}
|
|
14
|
+
export declare const isGitPluginSource: (source: string) => boolean;
|
|
15
|
+
/** Fetch and validate a fixed tree without running hooks, submodules or package scripts. */
|
|
16
|
+
export declare function withCatalogSource<T>(source: string, fn: (local: string, metadata: {
|
|
17
|
+
origin: string;
|
|
18
|
+
commit?: string;
|
|
19
|
+
importManifest?: Record<string, unknown>;
|
|
20
|
+
}) => T | Promise<T>): Promise<T>;
|
|
21
|
+
export declare const pluginSourceKey: (source: string) => string;
|