@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,132 @@
|
|
|
1
|
+
import { commandRegistry } from "../registry.js";
|
|
2
|
+
//#region src/chat-commands/builtins/skill.ts
|
|
3
|
+
function tokenizeArgs(input) {
|
|
4
|
+
const out = [];
|
|
5
|
+
let current = "";
|
|
6
|
+
let quote = null;
|
|
7
|
+
let escaping = false;
|
|
8
|
+
for (const ch of input) {
|
|
9
|
+
if (escaping) {
|
|
10
|
+
current += ch;
|
|
11
|
+
escaping = false;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
if (ch === "\\") {
|
|
15
|
+
escaping = true;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (quote) {
|
|
19
|
+
if (ch === quote) quote = null;
|
|
20
|
+
else current += ch;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (ch === "\"" || ch === "'") {
|
|
24
|
+
quote = ch;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (/\s/.test(ch)) {
|
|
28
|
+
if (current) {
|
|
29
|
+
out.push(current);
|
|
30
|
+
current = "";
|
|
31
|
+
}
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
current += ch;
|
|
35
|
+
}
|
|
36
|
+
if (current) out.push(current);
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
function usage() {
|
|
40
|
+
return [
|
|
41
|
+
"usage: /skill install <source> [--ref <ref>] [--path <dir>] [--id <skillId>] [--workspace|--global] [--force]",
|
|
42
|
+
"",
|
|
43
|
+
"source may be a Git URL, GitHub repository URL, https .zip/.tar.gz URL, file:// URL, or local archive/path.",
|
|
44
|
+
"Default target is the current workspace. Use --global only for personal skills shared by all projects."
|
|
45
|
+
].join("\n");
|
|
46
|
+
}
|
|
47
|
+
function parseInstallArgs(args) {
|
|
48
|
+
const tokens = tokenizeArgs(args);
|
|
49
|
+
const source = tokens.shift();
|
|
50
|
+
if (!source) throw new Error(usage());
|
|
51
|
+
const parsed = { source };
|
|
52
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
53
|
+
const token = tokens[i];
|
|
54
|
+
const next = () => {
|
|
55
|
+
const value = tokens[++i];
|
|
56
|
+
if (!value) throw new Error(`Missing value for ${token}`);
|
|
57
|
+
return value;
|
|
58
|
+
};
|
|
59
|
+
if (token === "--ref") parsed.ref = next();
|
|
60
|
+
else if (token === "--path") parsed.path = next();
|
|
61
|
+
else if (token === "--id" || token === "--skill-id") parsed.skillId = next();
|
|
62
|
+
else if (token === "--workspace") parsed.target = "workspace";
|
|
63
|
+
else if (token === "--global") parsed.target = "global";
|
|
64
|
+
else if (token === "--force") parsed.force = true;
|
|
65
|
+
else if (token === "--strict-scan") parsed.strictScan = true;
|
|
66
|
+
else throw new Error(`Unknown option: ${token}\n\n${usage()}`);
|
|
67
|
+
}
|
|
68
|
+
return parsed;
|
|
69
|
+
}
|
|
70
|
+
const skillCommand = {
|
|
71
|
+
id: "system.skill",
|
|
72
|
+
name: "skill",
|
|
73
|
+
aliases: ["skills"],
|
|
74
|
+
description: "Install skills from explicit sources. Subcommands: install <source>",
|
|
75
|
+
category: "tool",
|
|
76
|
+
scope: ["global", "private"],
|
|
77
|
+
acceptsArgs: true,
|
|
78
|
+
examples: ["/skill install https://github.com/org/repo", "/skill install https://example.com/skill.zip --id my-skill --force"],
|
|
79
|
+
handler: async (ctx, args) => {
|
|
80
|
+
const trimmed = args.trim();
|
|
81
|
+
const [subRaw, ...rest] = trimmed ? trimmed.split(/\s+/) : [];
|
|
82
|
+
const sub = subRaw?.toLowerCase();
|
|
83
|
+
if (!sub || sub === "help") return {
|
|
84
|
+
content: usage(),
|
|
85
|
+
success: true
|
|
86
|
+
};
|
|
87
|
+
if (sub !== "install") return {
|
|
88
|
+
content: `Unknown subcommand "${subRaw}". Available: install.\n\n${usage()}`,
|
|
89
|
+
success: false
|
|
90
|
+
};
|
|
91
|
+
if (!ctx.installSkillFromSource) return {
|
|
92
|
+
content: "Skill installation is not available in this context.",
|
|
93
|
+
success: false
|
|
94
|
+
};
|
|
95
|
+
let parsed;
|
|
96
|
+
try {
|
|
97
|
+
parsed = parseInstallArgs(rest.join(" "));
|
|
98
|
+
} catch (err) {
|
|
99
|
+
return {
|
|
100
|
+
content: err instanceof Error ? err.message : String(err),
|
|
101
|
+
success: false
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
await ctx.setTyping(true);
|
|
105
|
+
try {
|
|
106
|
+
const result = await ctx.installSkillFromSource(parsed);
|
|
107
|
+
return {
|
|
108
|
+
content: [
|
|
109
|
+
`Installed skill "${result.skillId}".`,
|
|
110
|
+
`Target: ${result.target ?? parsed.target ?? "workspace"}`,
|
|
111
|
+
`Source: ${result.source} (${result.kind})`,
|
|
112
|
+
`Path: ${result.path}`,
|
|
113
|
+
`Tree hash: ${result.contentHash.slice(0, 16)}`
|
|
114
|
+
].join("\n"),
|
|
115
|
+
success: true,
|
|
116
|
+
metadata: { skillInstall: result }
|
|
117
|
+
};
|
|
118
|
+
} catch (err) {
|
|
119
|
+
return {
|
|
120
|
+
content: `Skill install failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
121
|
+
success: false
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
function registerSkillCommand() {
|
|
127
|
+
commandRegistry.register(skillCommand);
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
130
|
+
export { registerSkillCommand };
|
|
131
|
+
|
|
132
|
+
//# sourceMappingURL=skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.js","names":[],"sources":["../../../../src/chat-commands/builtins/skill.ts"],"sourcesContent":["import { commandRegistry } from '../registry.js';\nimport type { CommandContext, CommandDefinition } from '../types.js';\n\nfunction tokenizeArgs(input: string): string[] {\n const out: string[] = [];\n let current = '';\n let quote: '\"' | \"'\" | null = null;\n let escaping = false;\n for (const ch of input) {\n if (escaping) {\n current += ch;\n escaping = false;\n continue;\n }\n if (ch === '\\\\') {\n escaping = true;\n continue;\n }\n if (quote) {\n if (ch === quote) quote = null;\n else current += ch;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch;\n continue;\n }\n if (/\\s/.test(ch)) {\n if (current) {\n out.push(current);\n current = '';\n }\n continue;\n }\n current += ch;\n }\n if (current) out.push(current);\n return out;\n}\n\nfunction usage(): string {\n return [\n 'usage: /skill install <source> [--ref <ref>] [--path <dir>] [--id <skillId>] [--workspace|--global] [--force]',\n '',\n 'source may be a Git URL, GitHub repository URL, https .zip/.tar.gz URL, file:// URL, or local archive/path.',\n 'Default target is the current workspace. Use --global only for personal skills shared by all projects.',\n ].join('\\n');\n}\n\ntype ParsedInstallArgs = {\n source: string;\n ref?: string;\n path?: string;\n skillId?: string;\n target?: 'workspace' | 'global';\n force?: boolean;\n strictScan?: boolean;\n};\n\nfunction parseInstallArgs(args: string): ParsedInstallArgs {\n const tokens = tokenizeArgs(args);\n const source = tokens.shift();\n if (!source) throw new Error(usage());\n\n const parsed: ParsedInstallArgs = { source };\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i];\n const next = () => {\n const value = tokens[++i];\n if (!value) throw new Error(`Missing value for ${token}`);\n return value;\n };\n if (token === '--ref') parsed.ref = next();\n else if (token === '--path') parsed.path = next();\n else if (token === '--id' || token === '--skill-id') parsed.skillId = next();\n else if (token === '--workspace') parsed.target = 'workspace';\n else if (token === '--global') parsed.target = 'global';\n else if (token === '--force') parsed.force = true;\n else if (token === '--strict-scan') parsed.strictScan = true;\n else throw new Error(`Unknown option: ${token}\\n\\n${usage()}`);\n }\n return parsed;\n}\n\nconst skillCommand: CommandDefinition = {\n id: 'system.skill',\n name: 'skill',\n aliases: ['skills'],\n description: 'Install skills from explicit sources. Subcommands: install <source>',\n category: 'tool',\n scope: ['global', 'private'],\n acceptsArgs: true,\n examples: [\n '/skill install https://github.com/org/repo',\n '/skill install https://example.com/skill.zip --id my-skill --force',\n ],\n handler: async (ctx: CommandContext, args: string) => {\n const trimmed = args.trim();\n const [subRaw, ...rest] = trimmed ? trimmed.split(/\\s+/) : [];\n const sub = subRaw?.toLowerCase();\n if (!sub || sub === 'help') {\n return { content: usage(), success: true };\n }\n if (sub !== 'install') {\n return {\n content: `Unknown subcommand \"${subRaw}\". Available: install.\\n\\n${usage()}`,\n success: false,\n };\n }\n if (!ctx.installSkillFromSource) {\n return {\n content: 'Skill installation is not available in this context.',\n success: false,\n };\n }\n\n let parsed: ParsedInstallArgs;\n try {\n parsed = parseInstallArgs(rest.join(' '));\n } catch (err) {\n return {\n content: err instanceof Error ? err.message : String(err),\n success: false,\n };\n }\n\n await ctx.setTyping(true);\n try {\n const result = await ctx.installSkillFromSource(parsed);\n return {\n content: [\n `Installed skill \"${result.skillId}\".`,\n `Target: ${result.target ?? parsed.target ?? 'workspace'}`,\n `Source: ${result.source} (${result.kind})`,\n `Path: ${result.path}`,\n `Tree hash: ${result.contentHash.slice(0, 16)}`,\n ].join('\\n'),\n success: true,\n metadata: { skillInstall: result },\n };\n } catch (err) {\n return {\n content: `Skill install failed: ${err instanceof Error ? err.message : String(err)}`,\n success: false,\n };\n }\n },\n};\n\nexport function registerSkillCommand(): void {\n commandRegistry.register(skillCommand);\n}\n"],"mappings":"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"}
|
|
@@ -44,6 +44,8 @@ export interface CommandContextDeps {
|
|
|
44
44
|
abortCurrentTurn?: () => Promise<void>;
|
|
45
45
|
/** Reload skills from disk and refresh active agent prompts. */
|
|
46
46
|
reloadSkills?: () => Promise<void>;
|
|
47
|
+
/** Install a managed skill from an explicit source and refresh active agent prompts. */
|
|
48
|
+
installSkillFromSource?: CommandContext['installSkillFromSource'];
|
|
47
49
|
compactSession?: (sessionKey: string, options?: {
|
|
48
50
|
instructions?: string;
|
|
49
51
|
force?: boolean;
|
|
@@ -68,6 +70,7 @@ export declare class CommandContextImpl implements CommandContext {
|
|
|
68
70
|
readonly config: Config;
|
|
69
71
|
readonly abortCurrentTurn?: () => Promise<void>;
|
|
70
72
|
readonly reloadSkills?: () => Promise<void>;
|
|
73
|
+
readonly installSkillFromSource?: CommandContext['installSkillFromSource'];
|
|
71
74
|
readonly persistentGoalApis?: PersistentGoalApis;
|
|
72
75
|
readonly workflowRunApis?: CommandContext['workflowRunApis'];
|
|
73
76
|
private deps;
|
|
@@ -25,6 +25,7 @@ var CommandContextImpl = class {
|
|
|
25
25
|
config;
|
|
26
26
|
abortCurrentTurn;
|
|
27
27
|
reloadSkills;
|
|
28
|
+
installSkillFromSource;
|
|
28
29
|
persistentGoalApis;
|
|
29
30
|
workflowRunApis;
|
|
30
31
|
deps;
|
|
@@ -51,6 +52,7 @@ var CommandContextImpl = class {
|
|
|
51
52
|
await run();
|
|
52
53
|
};
|
|
53
54
|
}
|
|
55
|
+
if (deps.installSkillFromSource) this.installSkillFromSource = deps.installSkillFromSource;
|
|
54
56
|
this.persistentGoalApis = deps.persistentGoalApis;
|
|
55
57
|
if (deps.workflowRunService) this.workflowRunApis = {
|
|
56
58
|
service: deps.workflowRunService,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","names":[],"sources":["../../../src/chat-commands/context.ts"],"sourcesContent":["/**\n * Command Context Implementation\n * \n * Provides the concrete implementation of CommandContext interface,\n * bridging commands to core services (AgentService, SessionStore, etc.)\n */\n\nimport type {\n CommandContext,\n ReplyOptions,\n UIComponent,\n SessionInfo,\n ModelInfo,\n UsageStats,\n PlatformFeature,\n MessageSource,\n CompactSessionResult,\n} from './types.js';\nimport { getSessionDisplayName } from './session-key.js';\nimport type { Config } from '../config/schema.js';\nimport { getAgentDefaultModelRef } from '../config/schema.js';\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { SessionStore, SessionConfigStore } from '../session/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { saveConfig } from '../config/loader.js';\nimport type { ThinkLevel, ReasoningLevel, VerboseLevel } from '../agent/transcript/thinking-types.js';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport { effectiveWorkspacePathForSession } from '../session/session-workspace.js';\nimport { wrapMarkdownExportAsHtml } from '../session/chat-export.js';\nimport type { CompactionResult } from '../agent/memory/compaction.js';\nimport type { PersistentGoalApis } from '../agent/goals/persistent-goal-apis.js';\nimport type { WorkflowRunServiceLike } from '../workflows/service/workflow-run-service.types.js';\nimport { getProjectForSession } from '../projects/workspace.js';\n\nconst log = createLogger('CommandContext');\n\nexport interface CommandContextDeps {\n sessionKey: string;\n source: MessageSource;\n channelId: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n accountId?: string;\n threadId?: string;\n config: Config;\n bus: MessageBus;\n sessionStore: SessionStore;\n sessionConfigStore?: SessionConfigStore;\n /** After persisting session thinking, sync pi-agent in-memory state */\n applySessionThinkingLevel?: (sessionKey: string, level: ThinkLevel) => void;\n // Callbacks for platform-specific operations\n replyHandler: (text: string, options?: ReplyOptions) => Promise<void>;\n componentHandler?: (component: UIComponent) => Promise<void>;\n typingHandler?: (typing: boolean) => Promise<void>;\n supportedFeatures: PlatformFeature[];\n /** Called after session files are removed so in-memory agents match disk */\n invalidateAgentSession?: (sessionKey: string) => void;\n /** Reset session in place (archive + new session id); optional — falls back to clearSession */\n resetSession?: (sessionKey: string) => Promise<void>;\n // Model management (optional, will be injected)\n getCurrentModel?: () => string;\n switchModel?: (modelId: string) => Promise<boolean>;\n listModels?: () => Promise<ModelInfo[]>;\n getUsage?: () => Promise<UsageStats>;\n /** Stop current LLM turn and clear channel preview stream (Telegram draft, etc.) */\n abortCurrentTurn?: () => Promise<void>;\n /** Reload skills from disk and refresh active agent prompts. */\n reloadSkills?: () => Promise<void>;\n\n compactSession?: (\n sessionKey: string,\n options?: { instructions?: string; force?: boolean },\n ) => Promise<CompactionResult>;\n\n btwQuery?: (sessionKey: string, question: string) => Promise<{ text: string; error?: string }>;\n\n getSessionContextReport?: (\n sessionKey: string,\n mode: 'list' | 'detail' | 'json',\n ) => Promise<string>;\n\n persistentGoalApis?: PersistentGoalApis;\n workflowRunService?: WorkflowRunServiceLike;\n}\n\nexport class CommandContextImpl implements CommandContext {\n readonly sessionKey: string;\n readonly source: MessageSource;\n readonly channelId: string;\n readonly chatId: string;\n readonly senderId: string;\n readonly isGroup: boolean;\n readonly accountId?: string;\n readonly threadId?: string;\n readonly config: Config;\n readonly abortCurrentTurn?: () => Promise<void>;\n readonly reloadSkills?: () => Promise<void>;\n readonly persistentGoalApis?: PersistentGoalApis;\n readonly workflowRunApis?: CommandContext['workflowRunApis'];\n\n private deps: CommandContextDeps;\n\n constructor(deps: CommandContextDeps) {\n this.sessionKey = deps.sessionKey;\n this.source = deps.source;\n this.channelId = deps.channelId;\n this.chatId = deps.chatId;\n this.senderId = deps.senderId;\n this.isGroup = deps.isGroup;\n this.accountId = deps.accountId;\n this.threadId = deps.threadId;\n this.config = deps.config;\n this.deps = deps;\n\n if (deps.abortCurrentTurn) {\n const run = deps.abortCurrentTurn;\n this.abortCurrentTurn = async () => {\n await run();\n };\n }\n\n if (deps.reloadSkills) {\n const run = deps.reloadSkills;\n this.reloadSkills = async () => {\n await run();\n };\n }\n\n this.persistentGoalApis = deps.persistentGoalApis;\n if (deps.workflowRunService) {\n this.workflowRunApis = {\n service: deps.workflowRunService,\n startWorkflowRun: (params) => deps.workflowRunService!.startWorkflowRun(params),\n };\n }\n }\n\n private outboundMetadata(extra?: Record<string, unknown>): Record<string, unknown> {\n return {\n accountId: this.deps.accountId,\n threadId: this.deps.threadId,\n ...extra,\n };\n }\n\n // === Reply API ===\n\n async reply(text: string, options?: ReplyOptions): Promise<void> {\n await this.deps.replyHandler(text, options);\n }\n\n async replyComponent(component: UIComponent): Promise<void> {\n if (this.deps.componentHandler) {\n await this.deps.componentHandler(component);\n } else {\n // Fallback to text representation\n await this.reply(this.renderComponentAsText(component));\n }\n }\n\n async setTyping(typing: boolean): Promise<void> {\n if (this.deps.typingHandler) {\n await this.deps.typingHandler(typing);\n }\n }\n\n // === Session Management ===\n\n async getSession(): Promise<AgentMessage[]> {\n return this.deps.sessionStore.load(this.sessionKey);\n }\n\n async resetSession(): Promise<void> {\n if (this.deps.resetSession) {\n await this.deps.resetSession(this.sessionKey);\n } else if (typeof this.deps.sessionStore.reset === 'function') {\n const outcome = await this.deps.sessionStore.reset(this.sessionKey);\n if (!outcome) {\n throw new Error('Session not found');\n }\n this.deps.invalidateAgentSession?.(this.sessionKey);\n } else {\n await this.clearSession();\n return;\n }\n\n await this.deps.bus.publishOutbound({\n channel: this.source,\n chat_id: this.chatId,\n content: '✅ New session started. Previous transcript archived; model and session overrides kept.',\n type: 'message',\n metadata: this.outboundMetadata(),\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session reset');\n }\n\n async clearSession(): Promise<void> {\n // Archive first if has messages\n const messages = await this.getSession();\n if (messages.length > 0) {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey, messageCount: messages.length }, 'Session archived');\n }\n\n // Delete session\n await this.deps.sessionStore.deleteSession(this.sessionKey);\n this.deps.invalidateAgentSession?.(this.sessionKey);\n\n // Publish outbound message to confirm\n await this.deps.bus.publishOutbound({\n channel: this.source,\n chat_id: this.chatId,\n content: '✅ Session cleared.',\n type: 'message',\n metadata: this.outboundMetadata(),\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session cleared');\n }\n\n async archiveSession(): Promise<void> {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey }, 'Session archived');\n }\n\n async listSessions(): Promise<SessionInfo[]> {\n // TODO: Implement listSessions in SessionStore\n // For now, return current session only\n const messages = await this.getSession();\n return [{\n key: this.sessionKey,\n name: getSessionDisplayName(this.sessionKey),\n messageCount: messages.length,\n createdAt: new Date(),\n updatedAt: new Date(),\n isActive: true,\n }];\n }\n\n async switchSession(sessionKey: string): Promise<void> {\n // This is mainly for CLI/Web UI where you can switch between sessions\n // For Telegram, each chat has its own session\n log.info({ from: this.sessionKey, to: sessionKey }, 'Session switch requested');\n \n // Note: In the current architecture, switching session means\n // the next message will use a different sessionKey\n // The actual switch happens at the adapter level\n }\n\n // === Model Management ===\n\n getCurrentModel(): string {\n if (this.deps.getCurrentModel) {\n return this.deps.getCurrentModel();\n }\n \n return getAgentDefaultModelRef(this.config);\n }\n\n async listModels(): Promise<ModelInfo[]> {\n if (this.deps.listModels) {\n return this.deps.listModels();\n }\n \n // Fallback to empty list\n return [];\n }\n\n async switchModel(modelId: string): Promise<boolean> {\n if (this.deps.switchModel) {\n return this.deps.switchModel(modelId);\n }\n \n // No model manager available\n await this.reply('❌ Model switching not available in this context.');\n return false;\n }\n\n async getUsage(): Promise<UsageStats> {\n if (this.deps.getUsage) {\n return this.deps.getUsage();\n }\n \n // Fallback: calculate from session\n const messages = await this.getSession();\n let promptTokens = 0;\n let completionTokens = 0;\n \n for (const msg of messages) {\n if ('usage' in msg && msg.usage) {\n promptTokens += msg.usage.input || 0;\n completionTokens += msg.usage.output || 0;\n }\n }\n \n return {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n messageCount: messages.length,\n };\n }\n\n // === Platform Features ===\n\n supports(feature: PlatformFeature): boolean {\n return this.deps.supportedFeatures.includes(feature);\n }\n\n // === Configuration ===\n\n getConfig(): Config {\n return this.config;\n }\n\n async updateConfig(path: string, value: unknown): Promise<boolean> {\n try {\n // Update config object using path\n const keys = path.split('.');\n let target: Record<string, unknown> = this.config as Record<string, unknown>;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in target) || typeof target[key] !== 'object' || target[key] === null) {\n target[key] = {};\n }\n target = target[key] as Record<string, unknown>;\n }\n \n target[keys[keys.length - 1]] = value;\n \n // Save to disk\n await saveConfig(this.config);\n \n log.info({ path, value }, 'Config updated via command');\n return true;\n } catch (error) {\n log.error({ err: error, path, value }, 'Failed to update config');\n return false;\n }\n }\n\n // === Private Helpers ===\n\n // === Thinking Configuration ===\n\n /**\n * Get the session config store (if available)\n */\n getSessionConfigStore(): SessionConfigStore | undefined {\n return this.deps.sessionConfigStore;\n }\n\n /**\n * Get current thinking level (session override or default)\n */\n async getThinkingLevel(): Promise<ThinkLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.thinkingLevel) {\n return sessionConfig.thinkingLevel;\n }\n }\n return undefined;\n }\n\n /**\n * Set thinking level for this session\n */\n async setThinkingLevel(level: ThinkLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { thinkingLevel: level });\n }\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n syncAgentThinkingLevel(level: ThinkLevel): void {\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n async compactSession(options?: { instructions?: string; force?: boolean }): Promise<CompactSessionResult | null> {\n if (!this.deps.compactSession) {\n return null;\n }\n const r = await this.deps.compactSession(this.sessionKey, options);\n return {\n compacted: r.compacted,\n tokensBefore: r.tokensBefore,\n tokensAfter: r.tokensAfter,\n summary: r.summary,\n };\n }\n\n async btwQuery(question: string): Promise<{ text: string; error?: string }> {\n if (!this.deps.btwQuery) {\n return { text: '', error: 'Side questions are not available in this environment.' };\n }\n return this.deps.btwQuery(this.sessionKey, question);\n }\n\n async exportSessionToWorkspace(format: 'markdown' | 'html' | 'json'): Promise<{ path: string }> {\n const exportFmt = format === 'json' ? 'json' : 'markdown';\n let body = await this.deps.sessionStore.exportSession(this.sessionKey, exportFmt);\n if (format === 'html') {\n body = wrapMarkdownExportAsHtml(`Session ${this.sessionKey}`, body);\n }\n const sc = this.deps.sessionConfigStore\n ? await this.deps.sessionConfigStore.get(this.sessionKey)\n : null;\n const root = effectiveWorkspacePathForSession(\n this.config,\n this.sessionKey,\n sc,\n getProjectForSession(this.sessionKey),\n );\n const dir = join(root, 'exports');\n await mkdir(dir, { recursive: true });\n const safe = this.sessionKey.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 96);\n const ext = format === 'json' ? 'json' : format === 'html' ? 'html' : 'md';\n const name = `session-${safe}-${Date.now()}.${ext}`;\n const outPath = join(dir, name);\n await writeFile(outPath, body, 'utf-8');\n return { path: outPath };\n }\n\n async agentContextReport(mode: 'list' | 'detail' | 'json' = 'list'): Promise<string> {\n if (!this.deps.getSessionContextReport) {\n return 'Context report is not available in this environment.';\n }\n return this.deps.getSessionContextReport(this.sessionKey, mode);\n }\n\n /**\n * Get current reasoning level (session override or default)\n */\n async getReasoningLevel(): Promise<ReasoningLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.reasoningLevel) {\n return sessionConfig.reasoningLevel;\n }\n }\n return undefined;\n }\n\n /**\n * Set reasoning level for this session\n */\n async setReasoningLevel(level: ReasoningLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { reasoningLevel: level });\n }\n }\n\n /**\n * Get current verbose level (session override or default)\n */\n async getVerboseLevel(): Promise<VerboseLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.verboseLevel) {\n return sessionConfig.verboseLevel;\n }\n }\n return undefined;\n }\n\n /**\n * Set verbose level for this session\n */\n async setVerboseLevel(level: VerboseLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { verboseLevel: level });\n }\n }\n\n private renderComponentAsText(component: UIComponent): string {\n switch (component.type) {\n case 'buttons':\n return component.buttons.map(b => `[${b.text}]`).join(' ');\n \n case 'select':\n return component.options.map(o => `- ${o.label}`).join('\\n');\n \n case 'model-picker':\n return component.providers.map(p => \n `**${p.name}**\\n${p.models.map(m => ` - ${m.name}`).join('\\n')}`\n ).join('\\n\\n');\n \n case 'usage-display':\n return `📊 Usage Stats:\\n` +\n `📥 Prompt: ${component.stats.promptTokens.toLocaleString()} tokens\\n` +\n `📤 Completion: ${component.stats.completionTokens.toLocaleString()} tokens\\n` +\n `📊 Total: ${component.stats.totalTokens.toLocaleString()} tokens`;\n \n case 'session-list':\n return component.sessions.map(s => \n `${s.isActive ? '▶️' : ' '} ${s.key} (${s.messageCount} messages)`\n ).join('\\n');\n \n case 'text-input':\n return component.placeholder || 'Enter text...';\n \n default:\n return '[UI Component]';\n }\n }\n}\n\n/**\n * Create a command context from dependencies\n */\nexport function createCommandContext(deps: CommandContextDeps): CommandContext {\n return new CommandContextImpl(deps);\n}\n"],"mappings":";;;;;;;;;;;aAoB8D;aAIZ;aACD;AAWjD,MAAM,MAAM,aAAa,iBAAiB;AAoD1C,IAAa,qBAAb,MAA0D;CACxD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CAEA,YAAY,MAA0B;AACpC,OAAK,aAAa,KAAK;AACvB,OAAK,SAAS,KAAK;AACnB,OAAK,YAAY,KAAK;AACtB,OAAK,SAAS,KAAK;AACnB,OAAK,WAAW,KAAK;AACrB,OAAK,UAAU,KAAK;AACpB,OAAK,YAAY,KAAK;AACtB,OAAK,WAAW,KAAK;AACrB,OAAK,SAAS,KAAK;AACnB,OAAK,OAAO;AAEZ,MAAI,KAAK,kBAAkB;GACzB,MAAM,MAAM,KAAK;AACjB,QAAK,mBAAmB,YAAY;AAClC,UAAM,KAAK;;;AAIf,MAAI,KAAK,cAAc;GACrB,MAAM,MAAM,KAAK;AACjB,QAAK,eAAe,YAAY;AAC9B,UAAM,KAAK;;;AAIf,OAAK,qBAAqB,KAAK;AAC/B,MAAI,KAAK,mBACP,MAAK,kBAAkB;GACrB,SAAS,KAAK;GACd,mBAAmB,WAAW,KAAK,mBAAoB,iBAAiB,OAAO;GAChF;;CAIL,iBAAyB,OAA0D;AACjF,SAAO;GACL,WAAW,KAAK,KAAK;GACrB,UAAU,KAAK,KAAK;GACpB,GAAG;GACJ;;CAKH,MAAM,MAAM,MAAc,SAAuC;AAC/D,QAAM,KAAK,KAAK,aAAa,MAAM,QAAQ;;CAG7C,MAAM,eAAe,WAAuC;AAC1D,MAAI,KAAK,KAAK,iBACZ,OAAM,KAAK,KAAK,iBAAiB,UAAU;MAG3C,OAAM,KAAK,MAAM,KAAK,sBAAsB,UAAU,CAAC;;CAI3D,MAAM,UAAU,QAAgC;AAC9C,MAAI,KAAK,KAAK,cACZ,OAAM,KAAK,KAAK,cAAc,OAAO;;CAMzC,MAAM,aAAsC;AAC1C,SAAO,KAAK,KAAK,aAAa,KAAK,KAAK,WAAW;;CAGrD,MAAM,eAA8B;AAClC,MAAI,KAAK,KAAK,aACZ,OAAM,KAAK,KAAK,aAAa,KAAK,WAAW;WACpC,OAAO,KAAK,KAAK,aAAa,UAAU,YAAY;AAE7D,OAAI,CAAC,MADiB,KAAK,KAAK,aAAa,MAAM,KAAK,WAAW,CAEjE,OAAM,IAAI,MAAM,oBAAoB;AAEtC,QAAK,KAAK,yBAAyB,KAAK,WAAW;SAC9C;AACL,SAAM,KAAK,cAAc;AACzB;;AAGF,QAAM,KAAK,KAAK,IAAI,gBAAgB;GAClC,SAAS,KAAK;GACd,SAAS,KAAK;GACd,SAAS;GACT,MAAM;GACN,UAAU,KAAK,kBAAkB;GAClC,CAAC;AAEF,MAAI,KAAK,EAAE,YAAY,KAAK,YAAY,EAAE,gBAAgB;;CAG5D,MAAM,eAA8B;EAElC,MAAM,WAAW,MAAM,KAAK,YAAY;AACxC,MAAI,SAAS,SAAS,GAAG;AACvB,SAAM,KAAK,KAAK,aAAa,QAAQ,KAAK,WAAW;AACrD,OAAI,KAAK;IAAE,YAAY,KAAK;IAAY,cAAc,SAAS;IAAQ,EAAE,mBAAmB;;AAI9F,QAAM,KAAK,KAAK,aAAa,cAAc,KAAK,WAAW;AAC3D,OAAK,KAAK,yBAAyB,KAAK,WAAW;AAGnD,QAAM,KAAK,KAAK,IAAI,gBAAgB;GAClC,SAAS,KAAK;GACd,SAAS,KAAK;GACd,SAAS;GACT,MAAM;GACN,UAAU,KAAK,kBAAkB;GAClC,CAAC;AAEF,MAAI,KAAK,EAAE,YAAY,KAAK,YAAY,EAAE,kBAAkB;;CAG9D,MAAM,iBAAgC;AACpC,QAAM,KAAK,KAAK,aAAa,QAAQ,KAAK,WAAW;AACrD,MAAI,KAAK,EAAE,YAAY,KAAK,YAAY,EAAE,mBAAmB;;CAG/D,MAAM,eAAuC;EAG3C,MAAM,WAAW,MAAM,KAAK,YAAY;AACxC,SAAO,CAAC;GACN,KAAK,KAAK;GACV,MAAM,sBAAsB,KAAK,WAAW;GAC5C,cAAc,SAAS;GACvB,2BAAW,IAAI,MAAM;GACrB,2BAAW,IAAI,MAAM;GACrB,UAAU;GACX,CAAC;;CAGJ,MAAM,cAAc,YAAmC;AAGrD,MAAI,KAAK;GAAE,MAAM,KAAK;GAAY,IAAI;GAAY,EAAE,2BAA2B;;CASjF,kBAA0B;AACxB,MAAI,KAAK,KAAK,gBACZ,QAAO,KAAK,KAAK,iBAAiB;AAGpC,SAAO,wBAAwB,KAAK,OAAO;;CAG7C,MAAM,aAAmC;AACvC,MAAI,KAAK,KAAK,WACZ,QAAO,KAAK,KAAK,YAAY;AAI/B,SAAO,EAAE;;CAGX,MAAM,YAAY,SAAmC;AACnD,MAAI,KAAK,KAAK,YACZ,QAAO,KAAK,KAAK,YAAY,QAAQ;AAIvC,QAAM,KAAK,MAAM,mDAAmD;AACpE,SAAO;;CAGT,MAAM,WAAgC;AACpC,MAAI,KAAK,KAAK,SACZ,QAAO,KAAK,KAAK,UAAU;EAI7B,MAAM,WAAW,MAAM,KAAK,YAAY;EACxC,IAAI,eAAe;EACnB,IAAI,mBAAmB;AAEvB,OAAK,MAAM,OAAO,SAChB,KAAI,WAAW,OAAO,IAAI,OAAO;AAC/B,mBAAgB,IAAI,MAAM,SAAS;AACnC,uBAAoB,IAAI,MAAM,UAAU;;AAI5C,SAAO;GACL;GACA;GACA,aAAa,eAAe;GAC5B,cAAc,SAAS;GACxB;;CAKH,SAAS,SAAmC;AAC1C,SAAO,KAAK,KAAK,kBAAkB,SAAS,QAAQ;;CAKtD,YAAoB;AAClB,SAAO,KAAK;;CAGd,MAAM,aAAa,MAAc,OAAkC;AACjE,MAAI;GAEF,MAAM,OAAO,KAAK,MAAM,IAAI;GAC5B,IAAI,SAAkC,KAAK;AAE3C,QAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;IACxC,MAAM,MAAM,KAAK;AACjB,QAAI,EAAE,OAAO,WAAW,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,KACzE,QAAO,OAAO,EAAE;AAElB,aAAS,OAAO;;AAGlB,UAAO,KAAK,KAAK,SAAS,MAAM;AAGhC,SAAM,WAAW,KAAK,OAAO;AAE7B,OAAI,KAAK;IAAE;IAAM;IAAO,EAAE,6BAA6B;AACvD,UAAO;WACA,OAAO;AACd,OAAI,MAAM;IAAE,KAAK;IAAO;IAAM;IAAO,EAAE,0BAA0B;AACjE,UAAO;;;;;;CAWX,wBAAwD;AACtD,SAAO,KAAK,KAAK;;;;;CAMnB,MAAM,mBAAoD;EACxD,MAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,aAAa;GACf,MAAM,gBAAgB,MAAM,YAAY,IAAI,KAAK,WAAW;AAC5D,OAAI,eAAe,cACjB,QAAO,cAAc;;;;;;CAS3B,MAAM,iBAAiB,OAAkC;EACvD,MAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,YACF,OAAM,YAAY,OAAO,KAAK,YAAY,EAAE,eAAe,OAAO,CAAC;AAErE,OAAK,KAAK,4BAA4B,KAAK,YAAY,MAAM;;CAG/D,uBAAuB,OAAyB;AAC9C,OAAK,KAAK,4BAA4B,KAAK,YAAY,MAAM;;CAG/D,MAAM,eAAe,SAA4F;AAC/G,MAAI,CAAC,KAAK,KAAK,eACb,QAAO;EAET,MAAM,IAAI,MAAM,KAAK,KAAK,eAAe,KAAK,YAAY,QAAQ;AAClE,SAAO;GACL,WAAW,EAAE;GACb,cAAc,EAAE;GAChB,aAAa,EAAE;GACf,SAAS,EAAE;GACZ;;CAGH,MAAM,SAAS,UAA6D;AAC1E,MAAI,CAAC,KAAK,KAAK,SACb,QAAO;GAAE,MAAM;GAAI,OAAO;GAAyD;AAErF,SAAO,KAAK,KAAK,SAAS,KAAK,YAAY,SAAS;;CAGtD,MAAM,yBAAyB,QAAiE;EAC9F,MAAM,YAAY,WAAW,SAAS,SAAS;EAC/C,IAAI,OAAO,MAAM,KAAK,KAAK,aAAa,cAAc,KAAK,YAAY,UAAU;AACjF,MAAI,WAAW,OACb,QAAO,yBAAyB,WAAW,KAAK,cAAc,KAAK;EAErE,MAAM,KAAK,KAAK,KAAK,qBACjB,MAAM,KAAK,KAAK,mBAAmB,IAAI,KAAK,WAAW,GACvD;EAOJ,MAAM,MAAM,KANC,iCACX,KAAK,QACL,KAAK,YACL,IACA,qBAAqB,KAAK,WAAW,CAElB,EAAE,UAAU;AACjC,QAAM,MAAM,KAAK,EAAE,WAAW,MAAM,CAAC;EACrC,MAAM,OAAO,KAAK,WAAW,QAAQ,qBAAqB,IAAI,CAAC,MAAM,GAAG,GAAG;EAC3E,MAAM,MAAM,WAAW,SAAS,SAAS,WAAW,SAAS,SAAS;EAEtE,MAAM,UAAU,KAAK,KAAK,WADF,KAAK,GAAG,KAAK,KAAK,CAAC,GAAG,MACf;AAC/B,QAAM,UAAU,SAAS,MAAM,QAAQ;AACvC,SAAO,EAAE,MAAM,SAAS;;CAG1B,MAAM,mBAAmB,OAAmC,QAAyB;AACnF,MAAI,CAAC,KAAK,KAAK,wBACb,QAAO;AAET,SAAO,KAAK,KAAK,wBAAwB,KAAK,YAAY,KAAK;;;;;CAMjE,MAAM,oBAAyD;EAC7D,MAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,aAAa;GACf,MAAM,gBAAgB,MAAM,YAAY,IAAI,KAAK,WAAW;AAC5D,OAAI,eAAe,eACjB,QAAO,cAAc;;;;;;CAS3B,MAAM,kBAAkB,OAAsC;EAC5D,MAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,YACF,OAAM,YAAY,OAAO,KAAK,YAAY,EAAE,gBAAgB,OAAO,CAAC;;;;;CAOxE,MAAM,kBAAqD;EACzD,MAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,aAAa;GACf,MAAM,gBAAgB,MAAM,YAAY,IAAI,KAAK,WAAW;AAC5D,OAAI,eAAe,aACjB,QAAO,cAAc;;;;;;CAS3B,MAAM,gBAAgB,OAAoC;EACxD,MAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,YACF,OAAM,YAAY,OAAO,KAAK,YAAY,EAAE,cAAc,OAAO,CAAC;;CAItE,sBAA8B,WAAgC;AAC5D,UAAQ,UAAU,MAAlB;GACE,KAAK,UACH,QAAO,UAAU,QAAQ,KAAI,MAAK,IAAI,EAAE,KAAK,GAAG,CAAC,KAAK,IAAI;GAE5D,KAAK,SACH,QAAO,UAAU,QAAQ,KAAI,MAAK,KAAK,EAAE,QAAQ,CAAC,KAAK,KAAK;GAE9D,KAAK,eACH,QAAO,UAAU,UAAU,KAAI,MAC7B,KAAK,EAAE,KAAK,MAAM,EAAE,OAAO,KAAI,MAAK,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,GAChE,CAAC,KAAK,OAAO;GAEhB,KAAK,gBACH,QAAO,+BACS,UAAU,MAAM,aAAa,gBAAgB,CAAC,0BAC1C,UAAU,MAAM,iBAAiB,gBAAgB,CAAC,qBACvD,UAAU,MAAM,YAAY,gBAAgB,CAAC;GAE9D,KAAK,eACH,QAAO,UAAU,SAAS,KAAI,MAC5B,GAAG,EAAE,WAAW,OAAO,KAAK,GAAG,EAAE,IAAI,IAAI,EAAE,aAAa,YACzD,CAAC,KAAK,KAAK;GAEd,KAAK,aACH,QAAO,UAAU,eAAe;GAElC,QACE,QAAO;;;;;;;AAQf,SAAgB,qBAAqB,MAA0C;AAC7E,QAAO,IAAI,mBAAmB,KAAK"}
|
|
1
|
+
{"version":3,"file":"context.js","names":[],"sources":["../../../src/chat-commands/context.ts"],"sourcesContent":["/**\n * Command Context Implementation\n * \n * Provides the concrete implementation of CommandContext interface,\n * bridging commands to core services (AgentService, SessionStore, etc.)\n */\n\nimport type {\n CommandContext,\n ReplyOptions,\n UIComponent,\n SessionInfo,\n ModelInfo,\n UsageStats,\n PlatformFeature,\n MessageSource,\n CompactSessionResult,\n} from './types.js';\nimport { getSessionDisplayName } from './session-key.js';\nimport type { Config } from '../config/schema.js';\nimport { getAgentDefaultModelRef } from '../config/schema.js';\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { SessionStore, SessionConfigStore } from '../session/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { saveConfig } from '../config/loader.js';\nimport type { ThinkLevel, ReasoningLevel, VerboseLevel } from '../agent/transcript/thinking-types.js';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport { effectiveWorkspacePathForSession } from '../session/session-workspace.js';\nimport { wrapMarkdownExportAsHtml } from '../session/chat-export.js';\nimport type { CompactionResult } from '../agent/memory/compaction.js';\nimport type { PersistentGoalApis } from '../agent/goals/persistent-goal-apis.js';\nimport type { WorkflowRunServiceLike } from '../workflows/service/workflow-run-service.types.js';\nimport { getProjectForSession } from '../projects/workspace.js';\n\nconst log = createLogger('CommandContext');\n\nexport interface CommandContextDeps {\n sessionKey: string;\n source: MessageSource;\n channelId: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n accountId?: string;\n threadId?: string;\n config: Config;\n bus: MessageBus;\n sessionStore: SessionStore;\n sessionConfigStore?: SessionConfigStore;\n /** After persisting session thinking, sync pi-agent in-memory state */\n applySessionThinkingLevel?: (sessionKey: string, level: ThinkLevel) => void;\n // Callbacks for platform-specific operations\n replyHandler: (text: string, options?: ReplyOptions) => Promise<void>;\n componentHandler?: (component: UIComponent) => Promise<void>;\n typingHandler?: (typing: boolean) => Promise<void>;\n supportedFeatures: PlatformFeature[];\n /** Called after session files are removed so in-memory agents match disk */\n invalidateAgentSession?: (sessionKey: string) => void;\n /** Reset session in place (archive + new session id); optional — falls back to clearSession */\n resetSession?: (sessionKey: string) => Promise<void>;\n // Model management (optional, will be injected)\n getCurrentModel?: () => string;\n switchModel?: (modelId: string) => Promise<boolean>;\n listModels?: () => Promise<ModelInfo[]>;\n getUsage?: () => Promise<UsageStats>;\n /** Stop current LLM turn and clear channel preview stream (Telegram draft, etc.) */\n abortCurrentTurn?: () => Promise<void>;\n /** Reload skills from disk and refresh active agent prompts. */\n reloadSkills?: () => Promise<void>;\n /** Install a managed skill from an explicit source and refresh active agent prompts. */\n installSkillFromSource?: CommandContext['installSkillFromSource'];\n\n compactSession?: (\n sessionKey: string,\n options?: { instructions?: string; force?: boolean },\n ) => Promise<CompactionResult>;\n\n btwQuery?: (sessionKey: string, question: string) => Promise<{ text: string; error?: string }>;\n\n getSessionContextReport?: (\n sessionKey: string,\n mode: 'list' | 'detail' | 'json',\n ) => Promise<string>;\n\n persistentGoalApis?: PersistentGoalApis;\n workflowRunService?: WorkflowRunServiceLike;\n}\n\nexport class CommandContextImpl implements CommandContext {\n readonly sessionKey: string;\n readonly source: MessageSource;\n readonly channelId: string;\n readonly chatId: string;\n readonly senderId: string;\n readonly isGroup: boolean;\n readonly accountId?: string;\n readonly threadId?: string;\n readonly config: Config;\n readonly abortCurrentTurn?: () => Promise<void>;\n readonly reloadSkills?: () => Promise<void>;\n readonly installSkillFromSource?: CommandContext['installSkillFromSource'];\n readonly persistentGoalApis?: PersistentGoalApis;\n readonly workflowRunApis?: CommandContext['workflowRunApis'];\n\n private deps: CommandContextDeps;\n\n constructor(deps: CommandContextDeps) {\n this.sessionKey = deps.sessionKey;\n this.source = deps.source;\n this.channelId = deps.channelId;\n this.chatId = deps.chatId;\n this.senderId = deps.senderId;\n this.isGroup = deps.isGroup;\n this.accountId = deps.accountId;\n this.threadId = deps.threadId;\n this.config = deps.config;\n this.deps = deps;\n\n if (deps.abortCurrentTurn) {\n const run = deps.abortCurrentTurn;\n this.abortCurrentTurn = async () => {\n await run();\n };\n }\n\n if (deps.reloadSkills) {\n const run = deps.reloadSkills;\n this.reloadSkills = async () => {\n await run();\n };\n }\n\n if (deps.installSkillFromSource) {\n this.installSkillFromSource = deps.installSkillFromSource;\n }\n\n this.persistentGoalApis = deps.persistentGoalApis;\n if (deps.workflowRunService) {\n this.workflowRunApis = {\n service: deps.workflowRunService,\n startWorkflowRun: (params) => deps.workflowRunService!.startWorkflowRun(params),\n };\n }\n }\n\n private outboundMetadata(extra?: Record<string, unknown>): Record<string, unknown> {\n return {\n accountId: this.deps.accountId,\n threadId: this.deps.threadId,\n ...extra,\n };\n }\n\n // === Reply API ===\n\n async reply(text: string, options?: ReplyOptions): Promise<void> {\n await this.deps.replyHandler(text, options);\n }\n\n async replyComponent(component: UIComponent): Promise<void> {\n if (this.deps.componentHandler) {\n await this.deps.componentHandler(component);\n } else {\n // Fallback to text representation\n await this.reply(this.renderComponentAsText(component));\n }\n }\n\n async setTyping(typing: boolean): Promise<void> {\n if (this.deps.typingHandler) {\n await this.deps.typingHandler(typing);\n }\n }\n\n // === Session Management ===\n\n async getSession(): Promise<AgentMessage[]> {\n return this.deps.sessionStore.load(this.sessionKey);\n }\n\n async resetSession(): Promise<void> {\n if (this.deps.resetSession) {\n await this.deps.resetSession(this.sessionKey);\n } else if (typeof this.deps.sessionStore.reset === 'function') {\n const outcome = await this.deps.sessionStore.reset(this.sessionKey);\n if (!outcome) {\n throw new Error('Session not found');\n }\n this.deps.invalidateAgentSession?.(this.sessionKey);\n } else {\n await this.clearSession();\n return;\n }\n\n await this.deps.bus.publishOutbound({\n channel: this.source,\n chat_id: this.chatId,\n content: '✅ New session started. Previous transcript archived; model and session overrides kept.',\n type: 'message',\n metadata: this.outboundMetadata(),\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session reset');\n }\n\n async clearSession(): Promise<void> {\n // Archive first if has messages\n const messages = await this.getSession();\n if (messages.length > 0) {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey, messageCount: messages.length }, 'Session archived');\n }\n\n // Delete session\n await this.deps.sessionStore.deleteSession(this.sessionKey);\n this.deps.invalidateAgentSession?.(this.sessionKey);\n\n // Publish outbound message to confirm\n await this.deps.bus.publishOutbound({\n channel: this.source,\n chat_id: this.chatId,\n content: '✅ Session cleared.',\n type: 'message',\n metadata: this.outboundMetadata(),\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session cleared');\n }\n\n async archiveSession(): Promise<void> {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey }, 'Session archived');\n }\n\n async listSessions(): Promise<SessionInfo[]> {\n // TODO: Implement listSessions in SessionStore\n // For now, return current session only\n const messages = await this.getSession();\n return [{\n key: this.sessionKey,\n name: getSessionDisplayName(this.sessionKey),\n messageCount: messages.length,\n createdAt: new Date(),\n updatedAt: new Date(),\n isActive: true,\n }];\n }\n\n async switchSession(sessionKey: string): Promise<void> {\n // This is mainly for CLI/Web UI where you can switch between sessions\n // For Telegram, each chat has its own session\n log.info({ from: this.sessionKey, to: sessionKey }, 'Session switch requested');\n \n // Note: In the current architecture, switching session means\n // the next message will use a different sessionKey\n // The actual switch happens at the adapter level\n }\n\n // === Model Management ===\n\n getCurrentModel(): string {\n if (this.deps.getCurrentModel) {\n return this.deps.getCurrentModel();\n }\n \n return getAgentDefaultModelRef(this.config);\n }\n\n async listModels(): Promise<ModelInfo[]> {\n if (this.deps.listModels) {\n return this.deps.listModels();\n }\n \n // Fallback to empty list\n return [];\n }\n\n async switchModel(modelId: string): Promise<boolean> {\n if (this.deps.switchModel) {\n return this.deps.switchModel(modelId);\n }\n \n // No model manager available\n await this.reply('❌ Model switching not available in this context.');\n return false;\n }\n\n async getUsage(): Promise<UsageStats> {\n if (this.deps.getUsage) {\n return this.deps.getUsage();\n }\n \n // Fallback: calculate from session\n const messages = await this.getSession();\n let promptTokens = 0;\n let completionTokens = 0;\n \n for (const msg of messages) {\n if ('usage' in msg && msg.usage) {\n promptTokens += msg.usage.input || 0;\n completionTokens += msg.usage.output || 0;\n }\n }\n \n return {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n messageCount: messages.length,\n };\n }\n\n // === Platform Features ===\n\n supports(feature: PlatformFeature): boolean {\n return this.deps.supportedFeatures.includes(feature);\n }\n\n // === Configuration ===\n\n getConfig(): Config {\n return this.config;\n }\n\n async updateConfig(path: string, value: unknown): Promise<boolean> {\n try {\n // Update config object using path\n const keys = path.split('.');\n let target: Record<string, unknown> = this.config as Record<string, unknown>;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in target) || typeof target[key] !== 'object' || target[key] === null) {\n target[key] = {};\n }\n target = target[key] as Record<string, unknown>;\n }\n \n target[keys[keys.length - 1]] = value;\n \n // Save to disk\n await saveConfig(this.config);\n \n log.info({ path, value }, 'Config updated via command');\n return true;\n } catch (error) {\n log.error({ err: error, path, value }, 'Failed to update config');\n return false;\n }\n }\n\n // === Private Helpers ===\n\n // === Thinking Configuration ===\n\n /**\n * Get the session config store (if available)\n */\n getSessionConfigStore(): SessionConfigStore | undefined {\n return this.deps.sessionConfigStore;\n }\n\n /**\n * Get current thinking level (session override or default)\n */\n async getThinkingLevel(): Promise<ThinkLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.thinkingLevel) {\n return sessionConfig.thinkingLevel;\n }\n }\n return undefined;\n }\n\n /**\n * Set thinking level for this session\n */\n async setThinkingLevel(level: ThinkLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { thinkingLevel: level });\n }\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n syncAgentThinkingLevel(level: ThinkLevel): void {\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n async compactSession(options?: { instructions?: string; force?: boolean }): Promise<CompactSessionResult | null> {\n if (!this.deps.compactSession) {\n return null;\n }\n const r = await this.deps.compactSession(this.sessionKey, options);\n return {\n compacted: r.compacted,\n tokensBefore: r.tokensBefore,\n tokensAfter: r.tokensAfter,\n summary: r.summary,\n };\n }\n\n async btwQuery(question: string): Promise<{ text: string; error?: string }> {\n if (!this.deps.btwQuery) {\n return { text: '', error: 'Side questions are not available in this environment.' };\n }\n return this.deps.btwQuery(this.sessionKey, question);\n }\n\n async exportSessionToWorkspace(format: 'markdown' | 'html' | 'json'): Promise<{ path: string }> {\n const exportFmt = format === 'json' ? 'json' : 'markdown';\n let body = await this.deps.sessionStore.exportSession(this.sessionKey, exportFmt);\n if (format === 'html') {\n body = wrapMarkdownExportAsHtml(`Session ${this.sessionKey}`, body);\n }\n const sc = this.deps.sessionConfigStore\n ? await this.deps.sessionConfigStore.get(this.sessionKey)\n : null;\n const root = effectiveWorkspacePathForSession(\n this.config,\n this.sessionKey,\n sc,\n getProjectForSession(this.sessionKey),\n );\n const dir = join(root, 'exports');\n await mkdir(dir, { recursive: true });\n const safe = this.sessionKey.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 96);\n const ext = format === 'json' ? 'json' : format === 'html' ? 'html' : 'md';\n const name = `session-${safe}-${Date.now()}.${ext}`;\n const outPath = join(dir, name);\n await writeFile(outPath, body, 'utf-8');\n return { path: outPath };\n }\n\n async agentContextReport(mode: 'list' | 'detail' | 'json' = 'list'): Promise<string> {\n if (!this.deps.getSessionContextReport) {\n return 'Context report is not available in this environment.';\n }\n return this.deps.getSessionContextReport(this.sessionKey, mode);\n }\n\n /**\n * Get current reasoning level (session override or default)\n */\n async getReasoningLevel(): Promise<ReasoningLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.reasoningLevel) {\n return sessionConfig.reasoningLevel;\n }\n }\n return undefined;\n }\n\n /**\n * Set reasoning level for this session\n */\n async setReasoningLevel(level: ReasoningLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { reasoningLevel: level });\n }\n }\n\n /**\n * Get current verbose level (session override or default)\n */\n async getVerboseLevel(): Promise<VerboseLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.verboseLevel) {\n return sessionConfig.verboseLevel;\n }\n }\n return undefined;\n }\n\n /**\n * Set verbose level for this session\n */\n async setVerboseLevel(level: VerboseLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { verboseLevel: level });\n }\n }\n\n private renderComponentAsText(component: UIComponent): string {\n switch (component.type) {\n case 'buttons':\n return component.buttons.map(b => `[${b.text}]`).join(' ');\n \n case 'select':\n return component.options.map(o => `- ${o.label}`).join('\\n');\n \n case 'model-picker':\n return component.providers.map(p => \n `**${p.name}**\\n${p.models.map(m => ` - ${m.name}`).join('\\n')}`\n ).join('\\n\\n');\n \n case 'usage-display':\n return `📊 Usage Stats:\\n` +\n `📥 Prompt: ${component.stats.promptTokens.toLocaleString()} tokens\\n` +\n `📤 Completion: ${component.stats.completionTokens.toLocaleString()} tokens\\n` +\n `📊 Total: ${component.stats.totalTokens.toLocaleString()} tokens`;\n \n case 'session-list':\n return component.sessions.map(s => \n `${s.isActive ? '▶️' : ' '} ${s.key} (${s.messageCount} messages)`\n ).join('\\n');\n \n case 'text-input':\n return component.placeholder || 'Enter text...';\n \n default:\n return '[UI Component]';\n }\n }\n}\n\n/**\n * Create a command context from dependencies\n */\nexport function createCommandContext(deps: CommandContextDeps): CommandContext {\n return new CommandContextImpl(deps);\n}\n"],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@ export { registerGoalCommand } from './builtins/goal.js';
|
|
|
21
21
|
export { registerSubgoalCommand } from './builtins/subgoal.js';
|
|
22
22
|
export { registerWorkflowCommands } from './builtins/workflow.js';
|
|
23
23
|
export { registerReviewCommand } from './builtins/review.js';
|
|
24
|
+
export { registerSkillCommand } from './builtins/skill.js';
|
|
24
25
|
export { registerAgentEditCommand } from './agent-edit.js';
|
|
25
26
|
/**
|
|
26
27
|
* Initialize the command system with all built-in commands
|
|
@@ -12,6 +12,7 @@ import { registerGoalCommand } from "./builtins/goal.js";
|
|
|
12
12
|
import { registerSubgoalCommand } from "./builtins/subgoal.js";
|
|
13
13
|
import { registerWorkflowCommands } from "./builtins/workflow.js";
|
|
14
14
|
import { registerReviewCommand } from "./builtins/review.js";
|
|
15
|
+
import { registerSkillCommand } from "./builtins/skill.js";
|
|
15
16
|
import { registerAgentEditCommand } from "./agent-edit.js";
|
|
16
17
|
import { CommandContextImpl, createCommandContext } from "./context.js";
|
|
17
18
|
//#region src/chat-commands/index.ts
|
|
@@ -36,9 +37,10 @@ function initializeCommands() {
|
|
|
36
37
|
registerSubgoalCommand();
|
|
37
38
|
registerWorkflowCommands();
|
|
38
39
|
registerReviewCommand();
|
|
40
|
+
registerSkillCommand();
|
|
39
41
|
registerAgentEditCommand();
|
|
40
42
|
}
|
|
41
43
|
//#endregion
|
|
42
|
-
export { CommandContextImpl, CommandRegistry, commandRegistry, createCommandContext, generateSessionKey, getSessionDisplayName, initializeCommands, normalizeTelegramCommandName, parseSlashCommand, registerAgentEditCommand, registerConfigCommand, registerContextCommands, registerGoalCommand, registerModelCommands, registerReviewCommand, registerSessionCommands, registerSubgoalCommand, registerSystemCommands, registerTTSCommands, registerThinkingCommands, registerWorkflowCommands };
|
|
44
|
+
export { CommandContextImpl, CommandRegistry, commandRegistry, createCommandContext, generateSessionKey, getSessionDisplayName, initializeCommands, normalizeTelegramCommandName, parseSlashCommand, registerAgentEditCommand, registerConfigCommand, registerContextCommands, registerGoalCommand, registerModelCommands, registerReviewCommand, registerSessionCommands, registerSkillCommand, registerSubgoalCommand, registerSystemCommands, registerTTSCommands, registerThinkingCommands, registerWorkflowCommands };
|
|
43
45
|
|
|
44
46
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/chat-commands/index.ts"],"sourcesContent":["/**\n * Unified Command System\n *\n * Provides a platform-agnostic command system that works across\n * Telegram, Feishu, Web UI, CLI, and other channel surfaces.\n */\n\n// Built-in Commands (import first to avoid circular deps)\nimport { registerSessionCommands } from './builtins/session.js';\nimport { registerModelCommands } from './builtins/model.js';\nimport { registerSystemCommands } from './builtins/system.js';\nimport { registerTTSCommands } from './builtins/tts.js';\nimport { registerThinkingCommands } from './builtins/thinking.js';\nimport { registerConfigCommand } from './builtins/config.js';\nimport { registerContextCommands } from './builtins/context.js';\nimport { registerGoalCommand } from './builtins/goal.js';\nimport { registerSubgoalCommand } from './builtins/subgoal.js';\nimport { registerWorkflowCommands } from './builtins/workflow.js';\nimport { registerReviewCommand } from './builtins/review.js';\nimport { registerAgentEditCommand } from './agent-edit.js';\n\n// Types\nexport type {\n MessageSource,\n UnifiedMessage,\n PlatformMetadata,\n MessageAttachment,\n CommandDefinition,\n CommandCategory,\n CommandScope,\n CommandHandler,\n CommandResult,\n CommandContext,\n ReplyOptions,\n UIComponent,\n ButtonGroup,\n SelectMenu,\n ModelPicker,\n UsageDisplay,\n SessionList,\n TextInput,\n ProviderInfo,\n ModelInfo,\n UsageStats,\n SessionInfo,\n PlatformFeature,\n ChannelAdapter,\n ReplyPayload,\n} from './types.js';\n\n// Session display helpers\nexport { generateSessionKey, getSessionDisplayName, type SessionKeyContext } from './session-key.js';\n\n// Command parsing helpers\nexport { normalizeTelegramCommandName, parseSlashCommand } from './command-parse.js';\n\n// Registry\nexport { CommandRegistry, commandRegistry } from './registry.js';\nexport type { CommandRegistry as CommandRegistryType } from './types.js';\n\n// Context\nexport { CommandContextImpl, createCommandContext } from './context.js';\n\n// Built-in Commands\nexport { registerSessionCommands } from './builtins/session.js';\nexport { registerModelCommands } from './builtins/model.js';\nexport { registerSystemCommands } from './builtins/system.js';\nexport { registerTTSCommands } from './builtins/tts.js';\nexport { registerThinkingCommands } from './builtins/thinking.js';\nexport { registerConfigCommand } from './builtins/config.js';\nexport { registerContextCommands } from './builtins/context.js';\nexport { registerGoalCommand } from './builtins/goal.js';\nexport { registerSubgoalCommand } from './builtins/subgoal.js';\nexport { registerWorkflowCommands } from './builtins/workflow.js';\nexport { registerReviewCommand } from './builtins/review.js';\nexport { registerAgentEditCommand } from './agent-edit.js';\n\n/**\n * Initialize the command system with all built-in commands\n */\nexport function initializeCommands(): void {\n registerSessionCommands();\n registerModelCommands();\n registerSystemCommands();\n registerConfigCommand();\n registerContextCommands();\n registerTTSCommands();\n registerThinkingCommands();\n registerGoalCommand();\n registerSubgoalCommand();\n registerWorkflowCommands();\n registerReviewCommand();\n registerAgentEditCommand();\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/chat-commands/index.ts"],"sourcesContent":["/**\n * Unified Command System\n *\n * Provides a platform-agnostic command system that works across\n * Telegram, Feishu, Web UI, CLI, and other channel surfaces.\n */\n\n// Built-in Commands (import first to avoid circular deps)\nimport { registerSessionCommands } from './builtins/session.js';\nimport { registerModelCommands } from './builtins/model.js';\nimport { registerSystemCommands } from './builtins/system.js';\nimport { registerTTSCommands } from './builtins/tts.js';\nimport { registerThinkingCommands } from './builtins/thinking.js';\nimport { registerConfigCommand } from './builtins/config.js';\nimport { registerContextCommands } from './builtins/context.js';\nimport { registerGoalCommand } from './builtins/goal.js';\nimport { registerSubgoalCommand } from './builtins/subgoal.js';\nimport { registerWorkflowCommands } from './builtins/workflow.js';\nimport { registerReviewCommand } from './builtins/review.js';\nimport { registerSkillCommand } from './builtins/skill.js';\nimport { registerAgentEditCommand } from './agent-edit.js';\n\n// Types\nexport type {\n MessageSource,\n UnifiedMessage,\n PlatformMetadata,\n MessageAttachment,\n CommandDefinition,\n CommandCategory,\n CommandScope,\n CommandHandler,\n CommandResult,\n CommandContext,\n ReplyOptions,\n UIComponent,\n ButtonGroup,\n SelectMenu,\n ModelPicker,\n UsageDisplay,\n SessionList,\n TextInput,\n ProviderInfo,\n ModelInfo,\n UsageStats,\n SessionInfo,\n PlatformFeature,\n ChannelAdapter,\n ReplyPayload,\n} from './types.js';\n\n// Session display helpers\nexport { generateSessionKey, getSessionDisplayName, type SessionKeyContext } from './session-key.js';\n\n// Command parsing helpers\nexport { normalizeTelegramCommandName, parseSlashCommand } from './command-parse.js';\n\n// Registry\nexport { CommandRegistry, commandRegistry } from './registry.js';\nexport type { CommandRegistry as CommandRegistryType } from './types.js';\n\n// Context\nexport { CommandContextImpl, createCommandContext } from './context.js';\n\n// Built-in Commands\nexport { registerSessionCommands } from './builtins/session.js';\nexport { registerModelCommands } from './builtins/model.js';\nexport { registerSystemCommands } from './builtins/system.js';\nexport { registerTTSCommands } from './builtins/tts.js';\nexport { registerThinkingCommands } from './builtins/thinking.js';\nexport { registerConfigCommand } from './builtins/config.js';\nexport { registerContextCommands } from './builtins/context.js';\nexport { registerGoalCommand } from './builtins/goal.js';\nexport { registerSubgoalCommand } from './builtins/subgoal.js';\nexport { registerWorkflowCommands } from './builtins/workflow.js';\nexport { registerReviewCommand } from './builtins/review.js';\nexport { registerSkillCommand } from './builtins/skill.js';\nexport { registerAgentEditCommand } from './agent-edit.js';\n\n/**\n * Initialize the command system with all built-in commands\n */\nexport function initializeCommands(): void {\n registerSessionCommands();\n registerModelCommands();\n registerSystemCommands();\n registerConfigCommand();\n registerContextCommands();\n registerTTSCommands();\n registerThinkingCommands();\n registerGoalCommand();\n registerSubgoalCommand();\n registerWorkflowCommands();\n registerReviewCommand();\n registerSkillCommand();\n registerAgentEditCommand();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAkFA,SAAgB,qBAA2B;AACzC,0BAAyB;AACzB,wBAAuB;AACvB,yBAAwB;AACxB,wBAAuB;AACvB,0BAAyB;AACzB,sBAAqB;AACrB,2BAA0B;AAC1B,sBAAqB;AACrB,yBAAwB;AACxB,2BAA0B;AAC1B,wBAAuB;AACvB,uBAAsB;AACtB,2BAA0B"}
|
|
@@ -157,6 +157,23 @@ export interface CommandContext {
|
|
|
157
157
|
updateConfig?(path: string, value: unknown): Promise<boolean>;
|
|
158
158
|
/** Reload skills from disk and refresh active agent prompts. */
|
|
159
159
|
reloadSkills?(): Promise<void>;
|
|
160
|
+
/** Install a managed skill from an explicit source and refresh active agent prompts. */
|
|
161
|
+
installSkillFromSource?(opts: {
|
|
162
|
+
source: string;
|
|
163
|
+
ref?: string;
|
|
164
|
+
path?: string;
|
|
165
|
+
skillId?: string;
|
|
166
|
+
target?: 'workspace' | 'global';
|
|
167
|
+
force?: boolean;
|
|
168
|
+
strictScan?: boolean;
|
|
169
|
+
}): Promise<{
|
|
170
|
+
skillId: string;
|
|
171
|
+
path: string;
|
|
172
|
+
source: string;
|
|
173
|
+
kind: 'git' | 'archive';
|
|
174
|
+
contentHash: string;
|
|
175
|
+
target?: 'workspace' | 'global';
|
|
176
|
+
}>;
|
|
160
177
|
/** Persist session thinking level and sync in-memory agent (when wired) */
|
|
161
178
|
setThinkingLevel?(level: ThinkLevel): Promise<void>;
|
|
162
179
|
/**
|
|
@@ -23,6 +23,7 @@ const REGISTRY_COMMAND_MODULES = {
|
|
|
23
23
|
search: () => import("./commands/search.js"),
|
|
24
24
|
auth: () => import("./commands/auth.js"),
|
|
25
25
|
skills: () => import("./commands/skills.js"),
|
|
26
|
+
connectors: () => import("./commands/connectors.js"),
|
|
26
27
|
browser: () => import("./commands/browser.js"),
|
|
27
28
|
update: () => import("./commands/update.js"),
|
|
28
29
|
logs: () => import("./commands/logs.js"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-loaders.js","names":[],"sources":["../../../src/cli/command-loaders.ts"],"sourcesContent":["/**\n * Lazy command loaders.\n *\n * Modules here trigger their `register({...})` side effect on import; the\n * caller then mounts the requested command via `registry.installOne` (or via\n * the explicit registrar functions for non-registry commands).\n *\n * Keeping this map static-but-thunked means `bin.ts` short-circuits and\n * `runCli` can resolve a single subcommand without paying for unrelated\n * command modules.\n */\nimport type { Command } from 'commander';\nimport { resolveCliCatalogCommandPath } from './command-path-policy.js';\nimport { shouldLoadExtensionCliForCommandPath } from './command-startup-policy.js';\nimport { registry, type CLIContext } from './registry.js';\n\nexport type CommandLoader = () => Promise<unknown>;\n\nexport const REGISTRY_COMMAND_MODULES: Record<string, CommandLoader> = {\n init: () => import('./commands/init.js'),\n profile: () => import('./commands/profile.js'),\n setup: () => import('./commands/setup.js'),\n onboard: () => import('./commands/onboard.js'),\n agent: () => import('./commands/agent.js'),\n tui: () => import('./commands/tui.js'),\n gateway: () => import('./commands/gateway.js'),\n session: () => import('./commands/session.js'),\n project: () => import('./commands/project.js'),\n goal: () => import('./commands/goal.js'),\n config: () => import('./commands/config.js'),\n doctor: () => import('./commands/doctor/index.js'),\n image: () => import('./commands/image.js'),\n channels: () => import('./commands/channels.js'),\n models: () => import('./commands/models.js'),\n providers: () => import('./commands/providers.js'),\n voice: () => import('./commands/voice.js'),\n search: () => import('./commands/search.js'),\n auth: () => import('./commands/auth.js'),\n skills: () => import('./commands/skills.js'),\n browser: () => import('./commands/browser.js'),\n update: () => import('./commands/update.js'),\n logs: () => import('./commands/logs.js'),\n tunnel: () => import('./commands/tunnel.js'),\n tailscale: () => import('./commands/tailscale.js'),\n};\n\nexport interface NonRegistryMatcher {\n matches: (name: string) => boolean;\n load: (program: Command) => Promise<void>;\n}\n\nexport const NON_REGISTRY_COMMAND_MATCHERS: NonRegistryMatcher[] = [\n {\n matches: (name) => name === 'agents' || name.startsWith('agents:'),\n load: async (program) => {\n const { registerAgentsCli } = await import('./commands/agents.js');\n registerAgentsCli(program);\n },\n },\n {\n matches: (name) => name === 'extensions',\n load: async (program) => {\n const { registerExtensionCommands } = await import('./commands/extension.js');\n registerExtensionCommands(program);\n const commandPath = resolveCliCatalogCommandPath(process.argv);\n if (shouldLoadExtensionCliForCommandPath(commandPath)) {\n const { registerExtensionCliCommands } = await import('./extension-cli-register.js');\n await registerExtensionCliCommands(program);\n }\n },\n },\n];\n\nconst FLAGS_WITH_VALUE = new Set(['--config', '--workspace']);\n\n/**\n * Resolve which command module to load based on argv. Skips global flags\n * (`--verbose`/`--config <path>`/`--workspace <path>`) and treats\n * `help <cmd>` as if the user had typed `<cmd>`, so that `xopc help gateway`\n * loads only the gateway module.\n */\nexport function resolveCommandName(argv: string[]): string | undefined {\n let i = 2;\n let firstSubcommand: string | undefined;\n while (i < argv.length) {\n const arg = argv[i];\n if (!arg) {\n i += 1;\n continue;\n }\n if (arg.startsWith('-')) {\n i += FLAGS_WITH_VALUE.has(arg) ? 2 : 1;\n continue;\n }\n if (firstSubcommand === undefined) {\n firstSubcommand = arg;\n if (arg === 'help') {\n i += 1;\n continue;\n }\n return arg;\n }\n return arg;\n }\n return firstSubcommand;\n}\n\nexport async function tryLoadCommand(\n program: Command,\n ctx: CLIContext,\n name: string,\n getCtx?: () => CLIContext,\n): Promise<boolean> {\n const moduleLoader = REGISTRY_COMMAND_MODULES[name];\n if (moduleLoader) {\n await moduleLoader();\n const installed = registry.installOne(program, name, ctx, getCtx);\n if (installed && name === 'gateway') {\n const gatewayCmd = program.commands.find((command) => command.name() === 'gateway');\n if (gatewayCmd) {\n const { prepareGatewayCommandForArgv } = await import('./commands/gateway.js');\n await prepareGatewayCommandForArgv(gatewayCmd, ctx);\n }\n }\n return installed;\n }\n const matcher = NON_REGISTRY_COMMAND_MATCHERS.find((m) => m.matches(name));\n if (matcher) {\n await matcher.load(program);\n return true;\n }\n return false;\n}\n\nexport async function loadAllCommands(\n program: Command,\n ctx: CLIContext,\n getCtx?: () => CLIContext,\n): Promise<void> {\n // Sequential to keep registration order deterministic; registry.install\n // sorts by category and is stable within a category.\n for (const loader of Object.values(REGISTRY_COMMAND_MODULES)) {\n await loader();\n }\n registry.install(program, ctx, getCtx);\n for (const matcher of NON_REGISTRY_COMMAND_MATCHERS) {\n await matcher.load(program);\n }\n const gatewayCmd = program.commands.find((command) => command.name() === 'gateway');\n if (gatewayCmd) {\n const { prepareGatewayCommandForArgv } = await import('./commands/gateway.js');\n await prepareGatewayCommandForArgv(gatewayCmd, ctx);\n }\n}\n"],"mappings":";;;;AAkBA,MAAa,2BAA0D;CACrE,YAAY,OAAO;CACnB,eAAe,OAAO;CACtB,aAAa,OAAO;CACpB,eAAe,OAAO;CACtB,aAAa,OAAO;CACpB,WAAW,OAAO;CAClB,eAAe,OAAO;CACtB,eAAe,OAAO;CACtB,eAAe,OAAO;CACtB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,cAAc,OAAO;CACrB,aAAa,OAAO;CACpB,gBAAgB,OAAO;CACvB,cAAc,OAAO;CACrB,iBAAiB,OAAO;CACxB,aAAa,OAAO;CACpB,cAAc,OAAO;CACrB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,eAAe,OAAO;CACtB,cAAc,OAAO;CACrB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,iBAAiB,OAAO;CACzB;AAOD,MAAa,gCAAsD,CACjE;CACE,UAAU,SAAS,SAAS,YAAY,KAAK,WAAW,UAAU;CAClE,MAAM,OAAO,YAAY;EACvB,MAAM,EAAE,sBAAsB,MAAM,OAAO;AAC3C,oBAAkB,QAAQ;;CAE7B,EACD;CACE,UAAU,SAAS,SAAS;CAC5B,MAAM,OAAO,YAAY;EACvB,MAAM,EAAE,8BAA8B,MAAM,OAAO;AACnD,4BAA0B,QAAQ;AAElC,MAAI,qCADgB,6BAA6B,QAAQ,KACL,CAAC,EAAE;GACrD,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,SAAM,6BAA6B,QAAQ;;;CAGhD,CACF;AAED,MAAM,mBAAmB,IAAI,IAAI,CAAC,YAAY,cAAc,CAAC;;;;;;;AAQ7D,SAAgB,mBAAmB,MAAoC;CACrE,IAAI,IAAI;CACR,IAAI;AACJ,QAAO,IAAI,KAAK,QAAQ;EACtB,MAAM,MAAM,KAAK;AACjB,MAAI,CAAC,KAAK;AACR,QAAK;AACL;;AAEF,MAAI,IAAI,WAAW,IAAI,EAAE;AACvB,QAAK,iBAAiB,IAAI,IAAI,GAAG,IAAI;AACrC;;AAEF,MAAI,oBAAoB,KAAA,GAAW;AACjC,qBAAkB;AAClB,OAAI,QAAQ,QAAQ;AAClB,SAAK;AACL;;AAEF,UAAO;;AAET,SAAO;;AAET,QAAO;;AAGT,eAAsB,eACpB,SACA,KACA,MACA,QACkB;CAClB,MAAM,eAAe,yBAAyB;AAC9C,KAAI,cAAc;AAChB,QAAM,cAAc;EACpB,MAAM,YAAY,SAAS,WAAW,SAAS,MAAM,KAAK,OAAO;AACjE,MAAI,aAAa,SAAS,WAAW;GACnC,MAAM,aAAa,QAAQ,SAAS,MAAM,YAAY,QAAQ,MAAM,KAAK,UAAU;AACnF,OAAI,YAAY;IACd,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,UAAM,6BAA6B,YAAY,IAAI;;;AAGvD,SAAO;;CAET,MAAM,UAAU,8BAA8B,MAAM,MAAM,EAAE,QAAQ,KAAK,CAAC;AAC1E,KAAI,SAAS;AACX,QAAM,QAAQ,KAAK,QAAQ;AAC3B,SAAO;;AAET,QAAO;;AAGT,eAAsB,gBACpB,SACA,KACA,QACe;AAGf,MAAK,MAAM,UAAU,OAAO,OAAO,yBAAyB,CAC1D,OAAM,QAAQ;AAEhB,UAAS,QAAQ,SAAS,KAAK,OAAO;AACtC,MAAK,MAAM,WAAW,8BACpB,OAAM,QAAQ,KAAK,QAAQ;CAE7B,MAAM,aAAa,QAAQ,SAAS,MAAM,YAAY,QAAQ,MAAM,KAAK,UAAU;AACnF,KAAI,YAAY;EACd,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,QAAM,6BAA6B,YAAY,IAAI"}
|
|
1
|
+
{"version":3,"file":"command-loaders.js","names":[],"sources":["../../../src/cli/command-loaders.ts"],"sourcesContent":["/**\n * Lazy command loaders.\n *\n * Modules here trigger their `register({...})` side effect on import; the\n * caller then mounts the requested command via `registry.installOne` (or via\n * the explicit registrar functions for non-registry commands).\n *\n * Keeping this map static-but-thunked means `bin.ts` short-circuits and\n * `runCli` can resolve a single subcommand without paying for unrelated\n * command modules.\n */\nimport type { Command } from 'commander';\nimport { resolveCliCatalogCommandPath } from './command-path-policy.js';\nimport { shouldLoadExtensionCliForCommandPath } from './command-startup-policy.js';\nimport { registry, type CLIContext } from './registry.js';\n\nexport type CommandLoader = () => Promise<unknown>;\n\nexport const REGISTRY_COMMAND_MODULES: Record<string, CommandLoader> = {\n init: () => import('./commands/init.js'),\n profile: () => import('./commands/profile.js'),\n setup: () => import('./commands/setup.js'),\n onboard: () => import('./commands/onboard.js'),\n agent: () => import('./commands/agent.js'),\n tui: () => import('./commands/tui.js'),\n gateway: () => import('./commands/gateway.js'),\n session: () => import('./commands/session.js'),\n project: () => import('./commands/project.js'),\n goal: () => import('./commands/goal.js'),\n config: () => import('./commands/config.js'),\n doctor: () => import('./commands/doctor/index.js'),\n image: () => import('./commands/image.js'),\n channels: () => import('./commands/channels.js'),\n models: () => import('./commands/models.js'),\n providers: () => import('./commands/providers.js'),\n voice: () => import('./commands/voice.js'),\n search: () => import('./commands/search.js'),\n auth: () => import('./commands/auth.js'),\n skills: () => import('./commands/skills.js'),\n connectors: () => import('./commands/connectors.js'),\n browser: () => import('./commands/browser.js'),\n update: () => import('./commands/update.js'),\n logs: () => import('./commands/logs.js'),\n tunnel: () => import('./commands/tunnel.js'),\n tailscale: () => import('./commands/tailscale.js'),\n};\n\nexport interface NonRegistryMatcher {\n matches: (name: string) => boolean;\n load: (program: Command) => Promise<void>;\n}\n\nexport const NON_REGISTRY_COMMAND_MATCHERS: NonRegistryMatcher[] = [\n {\n matches: (name) => name === 'agents' || name.startsWith('agents:'),\n load: async (program) => {\n const { registerAgentsCli } = await import('./commands/agents.js');\n registerAgentsCli(program);\n },\n },\n {\n matches: (name) => name === 'extensions',\n load: async (program) => {\n const { registerExtensionCommands } = await import('./commands/extension.js');\n registerExtensionCommands(program);\n const commandPath = resolveCliCatalogCommandPath(process.argv);\n if (shouldLoadExtensionCliForCommandPath(commandPath)) {\n const { registerExtensionCliCommands } = await import('./extension-cli-register.js');\n await registerExtensionCliCommands(program);\n }\n },\n },\n];\n\nconst FLAGS_WITH_VALUE = new Set(['--config', '--workspace']);\n\n/**\n * Resolve which command module to load based on argv. Skips global flags\n * (`--verbose`/`--config <path>`/`--workspace <path>`) and treats\n * `help <cmd>` as if the user had typed `<cmd>`, so that `xopc help gateway`\n * loads only the gateway module.\n */\nexport function resolveCommandName(argv: string[]): string | undefined {\n let i = 2;\n let firstSubcommand: string | undefined;\n while (i < argv.length) {\n const arg = argv[i];\n if (!arg) {\n i += 1;\n continue;\n }\n if (arg.startsWith('-')) {\n i += FLAGS_WITH_VALUE.has(arg) ? 2 : 1;\n continue;\n }\n if (firstSubcommand === undefined) {\n firstSubcommand = arg;\n if (arg === 'help') {\n i += 1;\n continue;\n }\n return arg;\n }\n return arg;\n }\n return firstSubcommand;\n}\n\nexport async function tryLoadCommand(\n program: Command,\n ctx: CLIContext,\n name: string,\n getCtx?: () => CLIContext,\n): Promise<boolean> {\n const moduleLoader = REGISTRY_COMMAND_MODULES[name];\n if (moduleLoader) {\n await moduleLoader();\n const installed = registry.installOne(program, name, ctx, getCtx);\n if (installed && name === 'gateway') {\n const gatewayCmd = program.commands.find((command) => command.name() === 'gateway');\n if (gatewayCmd) {\n const { prepareGatewayCommandForArgv } = await import('./commands/gateway.js');\n await prepareGatewayCommandForArgv(gatewayCmd, ctx);\n }\n }\n return installed;\n }\n const matcher = NON_REGISTRY_COMMAND_MATCHERS.find((m) => m.matches(name));\n if (matcher) {\n await matcher.load(program);\n return true;\n }\n return false;\n}\n\nexport async function loadAllCommands(\n program: Command,\n ctx: CLIContext,\n getCtx?: () => CLIContext,\n): Promise<void> {\n // Sequential to keep registration order deterministic; registry.install\n // sorts by category and is stable within a category.\n for (const loader of Object.values(REGISTRY_COMMAND_MODULES)) {\n await loader();\n }\n registry.install(program, ctx, getCtx);\n for (const matcher of NON_REGISTRY_COMMAND_MATCHERS) {\n await matcher.load(program);\n }\n const gatewayCmd = program.commands.find((command) => command.name() === 'gateway');\n if (gatewayCmd) {\n const { prepareGatewayCommandForArgv } = await import('./commands/gateway.js');\n await prepareGatewayCommandForArgv(gatewayCmd, ctx);\n }\n}\n"],"mappings":";;;;AAkBA,MAAa,2BAA0D;CACrE,YAAY,OAAO;CACnB,eAAe,OAAO;CACtB,aAAa,OAAO;CACpB,eAAe,OAAO;CACtB,aAAa,OAAO;CACpB,WAAW,OAAO;CAClB,eAAe,OAAO;CACtB,eAAe,OAAO;CACtB,eAAe,OAAO;CACtB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,cAAc,OAAO;CACrB,aAAa,OAAO;CACpB,gBAAgB,OAAO;CACvB,cAAc,OAAO;CACrB,iBAAiB,OAAO;CACxB,aAAa,OAAO;CACpB,cAAc,OAAO;CACrB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,kBAAkB,OAAO;CACzB,eAAe,OAAO;CACtB,cAAc,OAAO;CACrB,YAAY,OAAO;CACnB,cAAc,OAAO;CACrB,iBAAiB,OAAO;CACzB;AAOD,MAAa,gCAAsD,CACjE;CACE,UAAU,SAAS,SAAS,YAAY,KAAK,WAAW,UAAU;CAClE,MAAM,OAAO,YAAY;EACvB,MAAM,EAAE,sBAAsB,MAAM,OAAO;AAC3C,oBAAkB,QAAQ;;CAE7B,EACD;CACE,UAAU,SAAS,SAAS;CAC5B,MAAM,OAAO,YAAY;EACvB,MAAM,EAAE,8BAA8B,MAAM,OAAO;AACnD,4BAA0B,QAAQ;AAElC,MAAI,qCADgB,6BAA6B,QAAQ,KACL,CAAC,EAAE;GACrD,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,SAAM,6BAA6B,QAAQ;;;CAGhD,CACF;AAED,MAAM,mBAAmB,IAAI,IAAI,CAAC,YAAY,cAAc,CAAC;;;;;;;AAQ7D,SAAgB,mBAAmB,MAAoC;CACrE,IAAI,IAAI;CACR,IAAI;AACJ,QAAO,IAAI,KAAK,QAAQ;EACtB,MAAM,MAAM,KAAK;AACjB,MAAI,CAAC,KAAK;AACR,QAAK;AACL;;AAEF,MAAI,IAAI,WAAW,IAAI,EAAE;AACvB,QAAK,iBAAiB,IAAI,IAAI,GAAG,IAAI;AACrC;;AAEF,MAAI,oBAAoB,KAAA,GAAW;AACjC,qBAAkB;AAClB,OAAI,QAAQ,QAAQ;AAClB,SAAK;AACL;;AAEF,UAAO;;AAET,SAAO;;AAET,QAAO;;AAGT,eAAsB,eACpB,SACA,KACA,MACA,QACkB;CAClB,MAAM,eAAe,yBAAyB;AAC9C,KAAI,cAAc;AAChB,QAAM,cAAc;EACpB,MAAM,YAAY,SAAS,WAAW,SAAS,MAAM,KAAK,OAAO;AACjE,MAAI,aAAa,SAAS,WAAW;GACnC,MAAM,aAAa,QAAQ,SAAS,MAAM,YAAY,QAAQ,MAAM,KAAK,UAAU;AACnF,OAAI,YAAY;IACd,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,UAAM,6BAA6B,YAAY,IAAI;;;AAGvD,SAAO;;CAET,MAAM,UAAU,8BAA8B,MAAM,MAAM,EAAE,QAAQ,KAAK,CAAC;AAC1E,KAAI,SAAS;AACX,QAAM,QAAQ,KAAK,QAAQ;AAC3B,SAAO;;AAET,QAAO;;AAGT,eAAsB,gBACpB,SACA,KACA,QACe;AAGf,MAAK,MAAM,UAAU,OAAO,OAAO,yBAAyB,CAC1D,OAAM,QAAQ;AAEhB,UAAS,QAAQ,SAAS,KAAK,OAAO;AACtC,MAAK,MAAM,WAAW,8BACpB,OAAM,QAAQ,KAAK,QAAQ;CAE7B,MAAM,aAAa,QAAQ,SAAS,MAAM,YAAY,QAAQ,MAAM,KAAK,UAAU;AACnF,KAAI,YAAY;EACd,MAAM,EAAE,iCAAiC,MAAM,OAAO;AACtD,QAAM,6BAA6B,YAAY,IAAI"}
|
|
@@ -115,6 +115,10 @@ const ROOT_HELP_COMMANDS = [
|
|
|
115
115
|
name: "skills",
|
|
116
116
|
description: "Manage skills"
|
|
117
117
|
},
|
|
118
|
+
{
|
|
119
|
+
name: "connectors",
|
|
120
|
+
description: "Browse and install verified connector capabilities from xopc-store"
|
|
121
|
+
},
|
|
118
122
|
{
|
|
119
123
|
name: "tailscale",
|
|
120
124
|
description: "Tailscale status for gateway remote access"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-manifest.js","names":[],"sources":["../../../src/cli/command-manifest.ts"],"sourcesContent":["export type RootHelpOption = {\n flags: string;\n description: string;\n};\n\nexport type RootHelpCommand = {\n name: string;\n description: string;\n};\n\nexport const ROOT_COMMAND_DESCRIPTION = 'Ultra-Lightweight Personal AI Assistant. Run `xopc` with no command to open the local TUI.';\n\nexport const ROOT_HELP_OPTIONS: RootHelpOption[] = [\n { flags: '-V, --version', description: 'output the version number' },\n { flags: '--verbose', description: 'Enable verbose logging (default: false)' },\n { flags: '--config <path>', description: 'Config file path' },\n { flags: '--workspace <path>', description: 'Workspace directory' },\n { flags: '-h, --help', description: 'display help for command' },\n];\n\nexport const ROOT_HELP_COMMANDS: RootHelpCommand[] = [\n { name: 'init [options]', description: 'Initialize xopc state directories, config, and agent workspace' },\n { name: 'setup [options]', description: 'Initialize config file and workspace directory' },\n { name: 'profile', description: 'Manage xopc state profiles (~/.xopc vs ~/.xopc-<name>)' },\n { name: 'onboard [options]', description: 'Interactive setup wizard for xopc (gateway uses schema defaults)' },\n { name: 'channels', description: 'Messaging channel configuration' },\n { name: 'auth', description: 'Manage authentication credentials' },\n { name: 'agent [options]', description: 'Chat with the AI agent' },\n { name: 'tui [options]', description: 'Interactive terminal UI (pi-tui)' },\n { name: 'tunnel', description: 'Manage FRP remote access tunnel' },\n { name: 'gateway [options]', description: 'Start the xopc gateway server' },\n { name: 'session', description: 'Session management commands' },\n { name: 'project', description: 'Manage long-running projects' },\n { name: 'doctor [options]', description: 'Check xopc installation health and diagnose common issues' },\n { name: 'update [options]', description: 'Check for and install xopc updates' },\n { name: 'logs', description: 'Manage and query logs' },\n { name: 'goal', description: 'Manage durable goals' },\n { name: 'config [options]', description: 'View and edit configuration' },\n { name: 'image', description: 'Inspect image provider availability' },\n { name: 'models [options]', description: 'List and manage models and model auth' },\n { name: 'providers', description: 'Manage LLM provider credentials (user-friendly hub over `xopc auth`)' },\n { name: 'voice', description: 'Configure text-to-speech (TTS) output' },\n { name: 'search', description: 'Manage web-search providers (brave / tavily / bing / searxng)' },\n { name: 'skills', description: 'Manage skills' },\n { name: 'tailscale', description: 'Tailscale status for gateway remote access' },\n { name: 'browser', description: 'Browser automation commands (uses Playwright)' },\n { name: 'agents', description: 'Manage agents (config + workspace)' },\n { name: 'extensions', description: 'Manage extensions' },\n { name: 'help [command]', description: 'display help for command' },\n];\n\nfunction formatRows(rows: Array<{ label: string; description: string }>): string {\n const labelWidth = Math.max(...rows.map((row) => row.label.length)) + 2;\n return rows.map((row) => ` ${row.label.padEnd(labelWidth)}${row.description}`).join('\\n');\n}\n\nexport function formatRootHelp(): string {\n const options = formatRows(ROOT_HELP_OPTIONS.map((option) => ({ label: option.flags, description: option.description })));\n const commands = formatRows(\n ROOT_HELP_COMMANDS.map((command) => ({ label: command.name, description: command.description })),\n );\n return `Usage: xopc [options] [command]\n\n${ROOT_COMMAND_DESCRIPTION}\n\nOptions:\n${options}\n\nCommands:\n${commands}`;\n}\n"],"mappings":";AAUA,MAAa,2BAA2B;AAExC,MAAa,oBAAsC;CACjD;EAAE,OAAO;EAAiB,aAAa;EAA6B;CACpE;EAAE,OAAO;EAAa,aAAa;EAA2C;CAC9E;EAAE,OAAO;EAAmB,aAAa;EAAoB;CAC7D;EAAE,OAAO;EAAsB,aAAa;EAAuB;CACnE;EAAE,OAAO;EAAc,aAAa;EAA4B;CACjE;AAED,MAAa,qBAAwC;CACnD;EAAE,MAAM;EAAkB,aAAa;EAAkE;CACzG;EAAE,MAAM;EAAmB,aAAa;EAAkD;CAC1F;EAAE,MAAM;EAAW,aAAa;EAA0D;CAC1F;EAAE,MAAM;EAAqB,aAAa;EAAoE;CAC9G;EAAE,MAAM;EAAY,aAAa;EAAmC;CACpE;EAAE,MAAM;EAAQ,aAAa;EAAqC;CAClE;EAAE,MAAM;EAAmB,aAAa;EAA0B;CAClE;EAAE,MAAM;EAAiB,aAAa;EAAoC;CAC1E;EAAE,MAAM;EAAU,aAAa;EAAmC;CAClE;EAAE,MAAM;EAAqB,aAAa;EAAiC;CAC3E;EAAE,MAAM;EAAW,aAAa;EAA+B;CAC/D;EAAE,MAAM;EAAW,aAAa;EAAgC;CAChE;EAAE,MAAM;EAAoB,aAAa;EAA6D;CACtG;EAAE,MAAM;EAAoB,aAAa;EAAsC;CAC/E;EAAE,MAAM;EAAQ,aAAa;EAAyB;CACtD;EAAE,MAAM;EAAQ,aAAa;EAAwB;CACrD;EAAE,MAAM;EAAoB,aAAa;EAA+B;CACxE;EAAE,MAAM;EAAS,aAAa;EAAuC;CACrE;EAAE,MAAM;EAAoB,aAAa;EAAyC;CAClF;EAAE,MAAM;EAAa,aAAa;EAAwE;CAC1G;EAAE,MAAM;EAAS,aAAa;EAAyC;CACvE;EAAE,MAAM;EAAU,aAAa;EAAiE;CAChG;EAAE,MAAM;EAAU,aAAa;EAAiB;CAChD;EAAE,MAAM;EAAa,aAAa;EAA8C;CAChF;EAAE,MAAM;EAAW,aAAa;EAAiD;CACjF;EAAE,MAAM;EAAU,aAAa;EAAsC;CACrE;EAAE,MAAM;EAAc,aAAa;EAAqB;CACxD;EAAE,MAAM;EAAkB,aAAa;EAA4B;CACpE;AAED,SAAS,WAAW,MAA6D;CAC/E,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,MAAM,OAAO,CAAC,GAAG;AACtE,QAAO,KAAK,KAAK,QAAQ,KAAK,IAAI,MAAM,OAAO,WAAW,GAAG,IAAI,cAAc,CAAC,KAAK,KAAK;;AAG5F,SAAgB,iBAAyB;AAKvC,QAAO;;EAEP,yBAAyB;;;EANT,WAAW,kBAAkB,KAAK,YAAY;EAAE,OAAO,OAAO;EAAO,aAAa,OAAO;EAAa,EAAE,CASjH,CAAC;;;EARS,WACf,mBAAmB,KAAK,aAAa;EAAE,OAAO,QAAQ;EAAM,aAAa,QAAQ;EAAa,EAAE,CAU1F"}
|
|
1
|
+
{"version":3,"file":"command-manifest.js","names":[],"sources":["../../../src/cli/command-manifest.ts"],"sourcesContent":["export type RootHelpOption = {\n flags: string;\n description: string;\n};\n\nexport type RootHelpCommand = {\n name: string;\n description: string;\n};\n\nexport const ROOT_COMMAND_DESCRIPTION = 'Ultra-Lightweight Personal AI Assistant. Run `xopc` with no command to open the local TUI.';\n\nexport const ROOT_HELP_OPTIONS: RootHelpOption[] = [\n { flags: '-V, --version', description: 'output the version number' },\n { flags: '--verbose', description: 'Enable verbose logging (default: false)' },\n { flags: '--config <path>', description: 'Config file path' },\n { flags: '--workspace <path>', description: 'Workspace directory' },\n { flags: '-h, --help', description: 'display help for command' },\n];\n\nexport const ROOT_HELP_COMMANDS: RootHelpCommand[] = [\n { name: 'init [options]', description: 'Initialize xopc state directories, config, and agent workspace' },\n { name: 'setup [options]', description: 'Initialize config file and workspace directory' },\n { name: 'profile', description: 'Manage xopc state profiles (~/.xopc vs ~/.xopc-<name>)' },\n { name: 'onboard [options]', description: 'Interactive setup wizard for xopc (gateway uses schema defaults)' },\n { name: 'channels', description: 'Messaging channel configuration' },\n { name: 'auth', description: 'Manage authentication credentials' },\n { name: 'agent [options]', description: 'Chat with the AI agent' },\n { name: 'tui [options]', description: 'Interactive terminal UI (pi-tui)' },\n { name: 'tunnel', description: 'Manage FRP remote access tunnel' },\n { name: 'gateway [options]', description: 'Start the xopc gateway server' },\n { name: 'session', description: 'Session management commands' },\n { name: 'project', description: 'Manage long-running projects' },\n { name: 'doctor [options]', description: 'Check xopc installation health and diagnose common issues' },\n { name: 'update [options]', description: 'Check for and install xopc updates' },\n { name: 'logs', description: 'Manage and query logs' },\n { name: 'goal', description: 'Manage durable goals' },\n { name: 'config [options]', description: 'View and edit configuration' },\n { name: 'image', description: 'Inspect image provider availability' },\n { name: 'models [options]', description: 'List and manage models and model auth' },\n { name: 'providers', description: 'Manage LLM provider credentials (user-friendly hub over `xopc auth`)' },\n { name: 'voice', description: 'Configure text-to-speech (TTS) output' },\n { name: 'search', description: 'Manage web-search providers (brave / tavily / bing / searxng)' },\n { name: 'skills', description: 'Manage skills' },\n { name: 'connectors', description: 'Browse and install verified connector capabilities from xopc-store' },\n { name: 'tailscale', description: 'Tailscale status for gateway remote access' },\n { name: 'browser', description: 'Browser automation commands (uses Playwright)' },\n { name: 'agents', description: 'Manage agents (config + workspace)' },\n { name: 'extensions', description: 'Manage extensions' },\n { name: 'help [command]', description: 'display help for command' },\n];\n\nfunction formatRows(rows: Array<{ label: string; description: string }>): string {\n const labelWidth = Math.max(...rows.map((row) => row.label.length)) + 2;\n return rows.map((row) => ` ${row.label.padEnd(labelWidth)}${row.description}`).join('\\n');\n}\n\nexport function formatRootHelp(): string {\n const options = formatRows(ROOT_HELP_OPTIONS.map((option) => ({ label: option.flags, description: option.description })));\n const commands = formatRows(\n ROOT_HELP_COMMANDS.map((command) => ({ label: command.name, description: command.description })),\n );\n return `Usage: xopc [options] [command]\n\n${ROOT_COMMAND_DESCRIPTION}\n\nOptions:\n${options}\n\nCommands:\n${commands}`;\n}\n"],"mappings":";AAUA,MAAa,2BAA2B;AAExC,MAAa,oBAAsC;CACjD;EAAE,OAAO;EAAiB,aAAa;EAA6B;CACpE;EAAE,OAAO;EAAa,aAAa;EAA2C;CAC9E;EAAE,OAAO;EAAmB,aAAa;EAAoB;CAC7D;EAAE,OAAO;EAAsB,aAAa;EAAuB;CACnE;EAAE,OAAO;EAAc,aAAa;EAA4B;CACjE;AAED,MAAa,qBAAwC;CACnD;EAAE,MAAM;EAAkB,aAAa;EAAkE;CACzG;EAAE,MAAM;EAAmB,aAAa;EAAkD;CAC1F;EAAE,MAAM;EAAW,aAAa;EAA0D;CAC1F;EAAE,MAAM;EAAqB,aAAa;EAAoE;CAC9G;EAAE,MAAM;EAAY,aAAa;EAAmC;CACpE;EAAE,MAAM;EAAQ,aAAa;EAAqC;CAClE;EAAE,MAAM;EAAmB,aAAa;EAA0B;CAClE;EAAE,MAAM;EAAiB,aAAa;EAAoC;CAC1E;EAAE,MAAM;EAAU,aAAa;EAAmC;CAClE;EAAE,MAAM;EAAqB,aAAa;EAAiC;CAC3E;EAAE,MAAM;EAAW,aAAa;EAA+B;CAC/D;EAAE,MAAM;EAAW,aAAa;EAAgC;CAChE;EAAE,MAAM;EAAoB,aAAa;EAA6D;CACtG;EAAE,MAAM;EAAoB,aAAa;EAAsC;CAC/E;EAAE,MAAM;EAAQ,aAAa;EAAyB;CACtD;EAAE,MAAM;EAAQ,aAAa;EAAwB;CACrD;EAAE,MAAM;EAAoB,aAAa;EAA+B;CACxE;EAAE,MAAM;EAAS,aAAa;EAAuC;CACrE;EAAE,MAAM;EAAoB,aAAa;EAAyC;CAClF;EAAE,MAAM;EAAa,aAAa;EAAwE;CAC1G;EAAE,MAAM;EAAS,aAAa;EAAyC;CACvE;EAAE,MAAM;EAAU,aAAa;EAAiE;CAChG;EAAE,MAAM;EAAU,aAAa;EAAiB;CAChD;EAAE,MAAM;EAAc,aAAa;EAAsE;CACzG;EAAE,MAAM;EAAa,aAAa;EAA8C;CAChF;EAAE,MAAM;EAAW,aAAa;EAAiD;CACjF;EAAE,MAAM;EAAU,aAAa;EAAsC;CACrE;EAAE,MAAM;EAAc,aAAa;EAAqB;CACxD;EAAE,MAAM;EAAkB,aAAa;EAA4B;CACpE;AAED,SAAS,WAAW,MAA6D;CAC/E,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,MAAM,OAAO,CAAC,GAAG;AACtE,QAAO,KAAK,KAAK,QAAQ,KAAK,IAAI,MAAM,OAAO,WAAW,GAAG,IAAI,cAAc,CAAC,KAAK,KAAK;;AAG5F,SAAgB,iBAAyB;AAKvC,QAAO;;EAEP,yBAAyB;;;EANT,WAAW,kBAAkB,KAAK,YAAY;EAAE,OAAO,OAAO;EAAO,aAAa,OAAO;EAAa,EAAE,CASjH,CAAC;;;EARS,WACf,mBAAmB,KAAK,aAAa;EAAE,OAAO,QAAQ;EAAM,aAAa,QAAQ;EAAa,EAAE,CAU1F"}
|
|
@@ -8,10 +8,10 @@ import { MessageBus, MessageBusShutdownError } from "../../infra/bus/queue.js";
|
|
|
8
8
|
import "../../infra/bus/index.js";
|
|
9
9
|
import { AgentService } from "../../agent/service.js";
|
|
10
10
|
import "../../agent/index.js";
|
|
11
|
-
import { getWorkspacePath } from "../../config/workspace-path-helpers.js";
|
|
12
|
-
import "../../config/index.js";
|
|
13
11
|
import { formatExamples, register } from "../registry.js";
|
|
14
12
|
import { getContextWithOpts } from "../context.js";
|
|
13
|
+
import { getWorkspacePath } from "../../config/workspace-path-helpers.js";
|
|
14
|
+
import "../../config/index.js";
|
|
15
15
|
import { listSessions } from "./agent/sessions.js";
|
|
16
16
|
import { renderStreamToTerminal } from "./agent/stream-renderer.js";
|
|
17
17
|
import { startInteractiveChat } from "./agent/interactive.js";
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
|
|
2
|
+
import { getStoreConnectorInstallPlan, installStoreConnector, listStoreConnectors } from "../../capabilities/store-connector.js";
|
|
3
|
+
import { register } from "../registry.js";
|
|
4
|
+
import { confirm } from "@inquirer/prompts";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
//#region src/cli/commands/connectors.ts
|
|
7
|
+
init_loader();
|
|
8
|
+
function parsePairs(values, option) {
|
|
9
|
+
const output = {};
|
|
10
|
+
for (const value of values ?? []) {
|
|
11
|
+
const index = value.indexOf("=");
|
|
12
|
+
const key = index > 0 ? value.slice(0, index).trim() : "";
|
|
13
|
+
const raw = index > 0 ? value.slice(index + 1) : "";
|
|
14
|
+
if (!key || !raw) throw new Error(`${option} must use KEY=VALUE.`);
|
|
15
|
+
output[key] = raw;
|
|
16
|
+
}
|
|
17
|
+
return output;
|
|
18
|
+
}
|
|
19
|
+
function printPlan(plan) {
|
|
20
|
+
console.log("");
|
|
21
|
+
console.log("Connector install review");
|
|
22
|
+
console.log(` Package: ${plan.packageName}@${plan.version}`);
|
|
23
|
+
console.log(` Name: ${plan.definition.displayName}`);
|
|
24
|
+
console.log(` Authentication: ${plan.definition.auth.mode}`);
|
|
25
|
+
console.log(` Endpoint: ${plan.definition.runtime.type === "mcp" ? String(plan.definition.runtime.serverTemplate.url) : "n/a"}`);
|
|
26
|
+
if (plan.permissions.data?.length) console.log(` Data permissions: ${plan.permissions.data.join(", ")}`);
|
|
27
|
+
if (plan.permissions.networkDomains?.length) console.log(` Network domains: ${plan.permissions.networkDomains.join(", ")}`);
|
|
28
|
+
console.log(" Local command execution: denied");
|
|
29
|
+
console.log("");
|
|
30
|
+
}
|
|
31
|
+
function createConnectorsCommand(ctx) {
|
|
32
|
+
const command = new Command("connectors").description("Browse and install verified connector capabilities from xopc-store");
|
|
33
|
+
command.command("list [query]").description("List connector capabilities from xopc-store").option("--category <category>", "Filter by category").option("--json", "Output JSON").action(async (query, options) => {
|
|
34
|
+
const result = await listStoreConnectors(loadConfig(ctx.configPath), {
|
|
35
|
+
q: query,
|
|
36
|
+
category: options.category,
|
|
37
|
+
page: 1,
|
|
38
|
+
pageSize: 50
|
|
39
|
+
});
|
|
40
|
+
if (options.json) {
|
|
41
|
+
console.log(JSON.stringify(result, null, 2));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (result.items.length === 0) {
|
|
45
|
+
console.log("No connector capabilities found.");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
for (const item of result.items) {
|
|
49
|
+
console.log(`${item.name}${item.latestVersion ? `@${item.latestVersion}` : ""}`);
|
|
50
|
+
console.log(` ${item.description}`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
command.command("install <packageName>").description("Verify and install a connector capability from xopc-store").option("--version <version>", "Install an exact version").option("--secret <KEY=VALUE>", "Provide a required secret; repeat for multiple values", (value, previous = []) => [...previous, value], []).option("--config-value <KEY=VALUE>", "Provide a connector config value; repeat for multiple values", (value, previous = []) => [...previous, value], []).option("-y, --yes", "Skip the interactive confirmation", false).action(async (packageName, options) => {
|
|
54
|
+
try {
|
|
55
|
+
const config = loadConfig(ctx.configPath);
|
|
56
|
+
printPlan(await getStoreConnectorInstallPlan(config, packageName, options.version));
|
|
57
|
+
if (!options.yes && process.stdin.isTTY) {
|
|
58
|
+
if (!await confirm({
|
|
59
|
+
message: "Install this connector?",
|
|
60
|
+
default: false
|
|
61
|
+
})) {
|
|
62
|
+
console.log("Install cancelled.");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const { instance } = await installStoreConnector(config, packageName, {
|
|
67
|
+
secrets: parsePairs(options.secret, "--secret"),
|
|
68
|
+
config: parsePairs(options.configValue, "--config-value")
|
|
69
|
+
}, options.version);
|
|
70
|
+
await saveConfig(config, ctx.configPath);
|
|
71
|
+
console.log(`Installed ${instance.displayName} (${instance.instanceId}).`);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
74
|
+
process.exitCode = 1;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return command;
|
|
78
|
+
}
|
|
79
|
+
register({
|
|
80
|
+
id: "connectors",
|
|
81
|
+
name: "connectors",
|
|
82
|
+
description: "Browse and install verified connector capabilities from xopc-store",
|
|
83
|
+
factory: createConnectorsCommand,
|
|
84
|
+
metadata: {
|
|
85
|
+
category: "setup",
|
|
86
|
+
examples: [
|
|
87
|
+
"xopc connectors list",
|
|
88
|
+
"xopc connectors install demo-connector",
|
|
89
|
+
"xopc connectors install api-connector --secret API_KEY=…"
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
//#endregion
|
|
94
|
+
export { createConnectorsCommand };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=connectors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectors.js","names":[],"sources":["../../../../src/cli/commands/connectors.ts"],"sourcesContent":["import { confirm } from '@inquirer/prompts';\nimport { Command } from 'commander';\n\nimport type { ConnectorInstallInput } from '../../connectors/types.js';\nimport { getStoreConnectorInstallPlan, installStoreConnector, listStoreConnectors } from '../../capabilities/store-connector.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport { register, type CLIContext } from '../registry.js';\n\nfunction parsePairs(values: string[] | undefined, option: string): Record<string, string> {\n const output: Record<string, string> = {};\n for (const value of values ?? []) {\n const index = value.indexOf('=');\n const key = index > 0 ? value.slice(0, index).trim() : '';\n const raw = index > 0 ? value.slice(index + 1) : '';\n if (!key || !raw) {\n throw new Error(`${option} must use KEY=VALUE.`);\n }\n output[key] = raw;\n }\n return output;\n}\n\nfunction printPlan(plan: Awaited<ReturnType<typeof getStoreConnectorInstallPlan>>): void {\n console.log('');\n console.log('Connector install review');\n console.log(` Package: ${plan.packageName}@${plan.version}`);\n console.log(` Name: ${plan.definition.displayName}`);\n console.log(` Authentication: ${plan.definition.auth.mode}`);\n console.log(` Endpoint: ${plan.definition.runtime.type === 'mcp' ? String(plan.definition.runtime.serverTemplate.url) : 'n/a'}`);\n if (plan.permissions.data?.length) console.log(` Data permissions: ${plan.permissions.data.join(', ')}`);\n if (plan.permissions.networkDomains?.length) console.log(` Network domains: ${plan.permissions.networkDomains.join(', ')}`);\n console.log(' Local command execution: denied');\n console.log('');\n}\n\nfunction createConnectorsCommand(ctx: CLIContext): Command {\n const command = new Command('connectors').description('Browse and install verified connector capabilities from xopc-store');\n\n command\n .command('list [query]')\n .description('List connector capabilities from xopc-store')\n .option('--category <category>', 'Filter by category')\n .option('--json', 'Output JSON')\n .action(async (query: string | undefined, options: { category?: string; json?: boolean }) => {\n const result = await listStoreConnectors(loadConfig(ctx.configPath), {\n q: query,\n category: options.category,\n page: 1,\n pageSize: 50,\n });\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n if (result.items.length === 0) {\n console.log('No connector capabilities found.');\n return;\n }\n for (const item of result.items) {\n console.log(`${item.name}${item.latestVersion ? `@${item.latestVersion}` : ''}`);\n console.log(` ${item.description}`);\n }\n });\n\n command\n .command('install <packageName>')\n .description('Verify and install a connector capability from xopc-store')\n .option('--version <version>', 'Install an exact version')\n .option('--secret <KEY=VALUE>', 'Provide a required secret; repeat for multiple values', (value, previous: string[] = []) => [...previous, value], [])\n .option('--config-value <KEY=VALUE>', 'Provide a connector config value; repeat for multiple values', (value, previous: string[] = []) => [...previous, value], [])\n .option('-y, --yes', 'Skip the interactive confirmation', false)\n .action(async (packageName: string, options: {\n version?: string;\n secret?: string[];\n configValue?: string[];\n yes?: boolean;\n }) => {\n try {\n const config = loadConfig(ctx.configPath);\n const plan = await getStoreConnectorInstallPlan(config, packageName, options.version);\n printPlan(plan);\n if (!options.yes && process.stdin.isTTY) {\n const accepted = await confirm({ message: 'Install this connector?', default: false });\n if (!accepted) {\n console.log('Install cancelled.');\n return;\n }\n }\n const input: ConnectorInstallInput = {\n secrets: parsePairs(options.secret, '--secret'),\n config: parsePairs(options.configValue, '--config-value'),\n };\n const { instance } = await installStoreConnector(config, packageName, input, options.version);\n await saveConfig(config, ctx.configPath);\n console.log(`Installed ${instance.displayName} (${instance.instanceId}).`);\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\n return command;\n}\n\nregister({\n id: 'connectors',\n name: 'connectors',\n description: 'Browse and install verified connector capabilities from xopc-store',\n factory: createConnectorsCommand,\n metadata: {\n category: 'setup',\n examples: [\n 'xopc connectors list',\n 'xopc connectors install demo-connector',\n 'xopc connectors install api-connector --secret API_KEY=…',\n ],\n },\n});\n\nexport { createConnectorsCommand };\n"],"mappings":"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"}
|
|
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
52
52
|
id: "database-schema",
|
|
53
53
|
label: "Database schema",
|
|
54
54
|
status: "pass",
|
|
55
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
55
|
+
message: `SQLite schema v${status.dbVersion} (current release v28).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|