@xopcai/xopc 0.0.103 → 0.0.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/README.zh-CN.md +7 -4
- package/dist/_virtual/_rolldown/runtime.js +2 -3
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/adapters/cli-login.d.ts +1 -1
- package/dist/extensions/feishu/src/adapters/cli-login.js +1 -1
- package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
- package/dist/extensions/feishu/src/adapters/gateway-setup.d.ts +2 -0
- package/dist/extensions/feishu/src/adapters/gateway-setup.js +225 -0
- package/dist/extensions/feishu/src/adapters/gateway-setup.js.map +1 -0
- package/dist/extensions/feishu/src/index.d.ts +8 -1
- package/dist/extensions/feishu/src/index.js +14 -1
- package/dist/extensions/feishu/src/index.js.map +1 -0
- package/dist/extensions/feishu/src/outbound/outbound-adapter.js +1 -1
- package/dist/extensions/feishu/src/plugin.d.ts +2 -1
- package/dist/extensions/feishu/src/plugin.js +2 -0
- package/dist/extensions/feishu/src/plugin.js.map +1 -1
- package/dist/extensions/feishu/src/streaming/streaming-adapter.js +1 -1
- package/dist/extensions/feishu/src/transport/webhook/monitor.js +1 -1
- package/dist/extensions/feishu/xopc.extension.json +66 -1
- package/dist/extensions/telegram/src/adapters/gateway-setup.d.ts +2 -0
- package/dist/extensions/telegram/src/adapters/gateway-setup.js +146 -0
- package/dist/extensions/telegram/src/adapters/gateway-setup.js.map +1 -0
- package/dist/extensions/telegram/src/adapters/security-adapter.js +1 -1
- package/dist/extensions/telegram/src/command-handler.js +1 -2
- package/dist/extensions/telegram/src/command-handler.js.map +1 -1
- package/dist/extensions/telegram/src/config-schema.js +2 -2
- package/dist/extensions/telegram/src/config-schema.js.map +1 -1
- package/dist/extensions/telegram/src/doctor.d.ts +1 -0
- package/dist/extensions/telegram/src/doctor.js +68 -0
- package/dist/extensions/telegram/src/doctor.js.map +1 -1
- package/dist/extensions/telegram/src/index.d.ts +8 -1
- package/dist/extensions/telegram/src/index.js +15 -2
- package/dist/extensions/telegram/src/index.js.map +1 -0
- package/dist/extensions/telegram/src/plugin.d.ts +13 -5
- package/dist/extensions/telegram/src/plugin.js +32 -12
- package/dist/extensions/telegram/src/plugin.js.map +1 -1
- package/dist/extensions/telegram/src/proxy-fetch.js +22 -5
- package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -1
- package/dist/extensions/telegram/xopc.extension.json +412 -5
- package/dist/extensions/weixin/src/adapters/onboard-cli.js +2 -2
- package/dist/extensions/weixin/src/adapters/onboard-cli.js.map +1 -1
- package/dist/extensions/weixin/src/api/api.js +1 -1
- package/dist/extensions/weixin/src/index.d.ts +8 -0
- package/dist/extensions/weixin/src/index.js +12 -1
- package/dist/extensions/weixin/src/index.js.map +1 -0
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.d.ts +2 -1
- package/dist/extensions/weixin/src/plugin.js +77 -2
- package/dist/extensions/weixin/src/plugin.js.map +1 -1
- package/dist/extensions/weixin/xopc.extension.json +52 -0
- package/dist/gateway/static/root/assets/agents-CvsBrBfi.js +396 -0
- package/dist/gateway/static/root/assets/{apps-page-C5RmwmTT.js → apps-page-L-IwQTe0.js} +1 -1
- package/dist/gateway/static/root/assets/browser-BLJWD7WI.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-D95KuPeP.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-CfkWXDAI.js +1 -0
- package/dist/gateway/static/root/assets/{dist-CWm8hTXZ.js → dist-C6vclgEL.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BzYgTkS9.js → extension-debug-page-D4JYAbsX.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BmTZH6gL.js → extension-page-_T62gi6e.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CkJbjyM-.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-CMoWY2Si.js → fetch-B5aiIguv.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-startup-retry-DqmLXhs6.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-config-api-HwJV1K_Y.js +1 -0
- package/dist/gateway/static/root/assets/index-BPYKW7FB.css +1 -0
- package/dist/gateway/static/root/assets/index-DvTb6wNR.js +4845 -0
- package/dist/gateway/static/root/assets/{logs-page-BjdQjHwk.js → logs-page-DsjtTjBy.js} +2 -2
- package/dist/gateway/static/root/assets/{note-detail-page-8Er4197b.js → note-detail-page-B2V7RhgD.js} +43 -43
- package/dist/gateway/static/root/assets/{note-time-CF3vf1jm.js → note-time-BG8GCTr4.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-xrcVBQ6Z.js +1 -0
- package/dist/gateway/static/root/assets/schema-form-S-QUvhul.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-CrQer6Au.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DujQl9c7.js +2 -0
- package/dist/gateway/static/root/assets/{settings-form-section-C7qA7y0J.js → settings-form-section-r1V7dRV6.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-C9nrONQ2.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Tvr5Mtq5.js → share-preview-page-DOFy0FNt.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-DmTsrs_a.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-HTvJlFLL.js → theme-store-Bo3j5Ovv.js} +1 -1
- package/dist/gateway/static/root/assets/url-WgQIjFZu.js +3 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-AjmUAlEQ.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-page.utils-CeBkAjP7.js → workflow-page.utils-DLEJ92gK.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-BnjjKrM1.js +27 -0
- package/dist/gateway/static/root/index.html +6 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +18 -6
- package/dist/src/agent/agent-manager.js +60 -35
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/builtin-agent-ids.d.ts +2 -0
- package/dist/src/agent/builtin-agent-ids.js +17 -0
- package/dist/src/agent/builtin-agent-ids.js.map +1 -0
- package/dist/src/agent/child-agent-factory.d.ts +4 -0
- package/dist/src/agent/child-agent-factory.js +28 -8
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/context/workspace-seed.js +1 -1
- package/dist/src/agent/context/workspace-templates/AGENTS.md +23 -184
- package/dist/src/agent/embedded/run-turn.js +8 -2
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +1 -1
- package/dist/src/agent/embedded/subscribe-session.js +33 -51
- package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
- package/dist/src/agent/embedded/types.d.ts +36 -35
- package/dist/src/agent/fallback/candidates.js +1 -1
- package/dist/src/agent/fallback/candidates.js.map +1 -1
- package/dist/src/agent/inbound/inbound-loop.js +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +24 -5
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/models/manager.d.ts +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/models/manager.js.map +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +4 -0
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -0
- package/dist/src/agent/service/direct-turn-helpers.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +1 -0
- package/dist/src/agent/service/process-direct-streaming.js +35 -18
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service-inbound-utils.d.ts +0 -1
- package/dist/src/agent/service-inbound-utils.js +1 -17
- package/dist/src/agent/service-inbound-utils.js.map +1 -1
- package/dist/src/agent/service.d.ts +4 -4
- package/dist/src/agent/service.js +27 -15
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-config-service.d.ts +1 -0
- package/dist/src/agent/session/session-config-service.js +9 -1
- package/dist/src/agent/session/session-config-service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.d.ts +2 -1
- package/dist/src/agent/session/session-inspector.js +4 -0
- package/dist/src/agent/session/session-inspector.js.map +1 -1
- package/dist/src/agent/skills/config.js +1 -3
- package/dist/src/agent/skills/config.js.map +1 -1
- package/dist/src/agent/skills/format-skills-prompt.d.ts +1 -0
- package/dist/src/agent/skills/format-skills-prompt.js +3 -2
- package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
- package/dist/src/agent/skills/hub-pull.js +1 -1
- package/dist/src/agent/skills/index.js +20 -5
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/installer.js +14 -27
- package/dist/src/agent/skills/installer.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +18 -4
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +11 -2
- 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 +2 -2
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
- package/dist/src/agent/skills/skill-manager.d.ts +4 -1
- package/dist/src/agent/skills/skill-manager.js +3 -3
- package/dist/src/agent/skills/skill-manager.js.map +1 -1
- package/dist/src/agent/skills/skill-view-path.d.ts +1 -17
- package/dist/src/agent/skills/skill-view-path.js +3 -66
- package/dist/src/agent/skills/skill-view-path.js.map +1 -1
- package/dist/src/agent/skills/test-framework.js +2 -3
- package/dist/src/agent/skills/test-framework.js.map +1 -1
- package/dist/src/agent/streaming/reasoning-visibility-sse.js +1 -0
- package/dist/src/agent/streaming/reasoning-visibility-sse.js.map +1 -1
- package/dist/src/agent/tool-manuals/browser.d.ts +1 -0
- package/{skills/browser/SKILL.md → dist/src/agent/tool-manuals/browser.js} +51 -54
- package/dist/src/agent/tool-manuals/browser.js.map +1 -0
- package/dist/src/agent/tool-manuals/index.d.ts +10 -0
- package/dist/src/agent/tool-manuals/index.js +28 -0
- package/dist/src/agent/tool-manuals/index.js.map +1 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.js +7 -5
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +5 -4
- package/dist/src/agent/tools/session-search-tool.js +1 -1
- package/dist/src/agent/tools/shell.js +1 -1
- package/dist/src/agent/tools/skills-tools.js +37 -8
- package/dist/src/agent/tools/skills-tools.js.map +1 -1
- package/dist/src/agent/tools/tool-manual-tool.d.ts +6 -0
- package/dist/src/agent/tools/tool-manual-tool.js +34 -0
- package/dist/src/agent/tools/tool-manual-tool.js.map +1 -0
- package/dist/src/agent/tools/web-extract.js +2 -2
- package/dist/src/agent/tools/web.js +1 -1
- package/dist/src/agent/workflow/catalog.d.ts +7 -2
- package/dist/src/agent/workflow/catalog.js +66 -25
- package/dist/src/agent/workflow/catalog.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.d.ts +3 -0
- package/dist/src/agent/workflow/subagent-runner.js +50 -4
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +10 -0
- package/dist/src/auth/credentials.js +10 -5
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/browser/actions/extension-registry-bridge.js +1 -1
- package/dist/src/browser/actions/registry.js +2 -2
- package/dist/src/browser/cdp-local-launcher.js +1 -1
- package/dist/src/browser/index.js +3 -3
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +1 -1
- package/dist/src/channels/catalog/channel-catalog-service.d.ts +11 -0
- package/dist/src/channels/catalog/channel-catalog-service.js +168 -0
- package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -0
- package/dist/src/channels/catalog/channel-catalog-types.d.ts +22 -0
- package/dist/src/channels/catalog/channel-catalog-types.js +1 -0
- package/dist/src/channels/dock.d.ts +0 -7
- package/dist/src/channels/dock.js +1 -21
- package/dist/src/channels/index.d.ts +1 -3
- package/dist/src/channels/index.js +1 -5
- package/dist/src/channels/lifecycle-supervisor.d.ts +1 -0
- package/dist/src/channels/lifecycle-supervisor.js +11 -0
- package/dist/src/channels/lifecycle-supervisor.js.map +1 -1
- package/dist/src/channels/manager.d.ts +1 -0
- package/dist/src/channels/manager.js +3 -0
- package/dist/src/channels/manager.js.map +1 -1
- package/dist/src/channels/pairing/pairing-channel.d.ts +2 -3
- package/dist/src/channels/pairing/pairing-messages.js +1 -1
- package/dist/src/channels/pairing/pairing-messages.js.map +1 -1
- package/dist/src/channels/pairing/pairing-service.d.ts +1 -1
- package/dist/src/channels/pairing/pairing-service.js +8 -27
- package/dist/src/channels/pairing/pairing-service.js.map +1 -1
- package/dist/src/channels/plugin-types.d.ts +3 -1
- package/dist/src/channels/plugins/types.adapters.d.ts +55 -2
- package/dist/src/channels/telegram/index.js +1 -1
- package/dist/src/chat-commands/builtins/config.js +4 -4
- package/dist/src/chat-commands/builtins/config.js.map +1 -1
- package/dist/src/chat-commands/config-paths.js +1 -1
- package/dist/src/chat-commands/config-paths.js.map +1 -1
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/cli/bin.js +1 -1
- package/dist/src/cli/command-manifest.js +1 -1
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agent.js +2 -2
- package/dist/src/cli/commands/agent.js.map +1 -1
- package/dist/src/cli/commands/agents.js +2 -4
- package/dist/src/cli/commands/agents.js.map +1 -1
- package/dist/src/cli/commands/auth.js +1 -1
- package/dist/src/cli/commands/browser-cli-helpers.js +1 -1
- package/dist/src/cli/commands/channels.d.ts +1 -5
- package/dist/src/cli/commands/channels.js +115 -281
- package/dist/src/cli/commands/channels.js.map +1 -1
- package/dist/src/cli/commands/config.js +2 -2
- package/dist/src/cli/commands/config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js +16 -69
- package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js +6 -4
- package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-plugins.js +2 -2
- package/dist/src/cli/commands/doctor/checks/channel-plugins.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +13 -9
- package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
- package/dist/src/cli/commands/extension-dev.js +2 -1
- package/dist/src/cli/commands/extension-dev.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +2 -1
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.js +2 -1
- package/dist/src/cli/commands/extension-pack.js.map +1 -1
- package/dist/src/cli/commands/models.js +7 -4
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard/channels/index.js +1 -1
- package/dist/src/cli/commands/onboard/channels/index.js.map +1 -1
- package/dist/src/cli/commands/onboard/channels/registry.d.ts +2 -1
- package/dist/src/cli/commands/onboard/channels/registry.js +32 -8
- package/dist/src/cli/commands/onboard/channels/registry.js.map +1 -1
- package/dist/src/cli/commands/onboard/model.js +8 -5
- package/dist/src/cli/commands/onboard/model.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +4 -6
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/setup-shared/runner.d.ts +1 -1
- package/dist/src/cli/commands/setup-shared/runner.js.map +1 -1
- package/dist/src/cli/commands/setup-shared/types.d.ts +1 -1
- package/dist/src/cli/commands/setup-shared/types.js.map +1 -1
- package/dist/src/cli/commands/tui.js +13 -5
- package/dist/src/cli/commands/tui.js.map +1 -1
- package/dist/src/cli/extension-cli-register.js +1 -1
- package/dist/src/commands/agents.config.d.ts +3 -3
- package/dist/src/commands/agents.config.js +7 -7
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.d.ts +1 -1
- package/dist/src/config/agent-profile.js +6 -2
- package/dist/src/config/agent-profile.js.map +1 -1
- package/dist/src/config/agent-typed-models.d.ts +2 -2
- package/dist/src/config/agent-typed-models.js +13 -2
- package/dist/src/config/agent-typed-models.js.map +1 -1
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/integration.d.ts +1 -1
- package/dist/src/config/loader.d.ts +0 -1
- package/dist/src/config/loader.js +4 -9
- package/dist/src/config/loader.js.map +1 -1
- package/dist/src/config/models-json.d.ts +6 -6
- package/dist/src/config/rules.js +2 -12
- package/dist/src/config/rules.js.map +1 -1
- package/dist/src/config/schema.d.ts +74 -47
- package/dist/src/config/schema.js +28 -66
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/validate-channel-configs.d.ts +0 -3
- package/dist/src/config/validate-channel-configs.js +29 -10
- package/dist/src/config/validate-channel-configs.js.map +1 -1
- package/dist/src/cron/executor.js +1 -4
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/extensions/activation-context.js +3 -1
- package/dist/src/extensions/activation-context.js.map +1 -1
- package/dist/src/extensions/activation-planner.js +12 -0
- package/dist/src/extensions/activation-planner.js.map +1 -1
- package/dist/src/extensions/api.d.ts +5 -1
- package/dist/src/extensions/api.js +12 -0
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/discover-extensions.js +17 -13
- package/dist/src/extensions/discover-extensions.js.map +1 -1
- package/dist/src/extensions/extension-metadata-snapshot.js +11 -5
- package/dist/src/extensions/extension-metadata-snapshot.js.map +1 -1
- package/dist/src/extensions/index.js +12 -4
- package/dist/src/extensions/index.js.map +1 -0
- package/dist/src/extensions/loader.d.ts +5 -1
- package/dist/src/extensions/loader.js +12 -11
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/manifest-registry.js +98 -93
- package/dist/src/extensions/manifest-registry.js.map +1 -1
- package/dist/src/extensions/normalize-manifest.js +91 -15
- package/dist/src/extensions/normalize-manifest.js.map +1 -1
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/extensions/sdk/testing.js +4 -0
- package/dist/src/extensions/sdk/testing.js.map +1 -1
- package/dist/src/extensions/types/core.d.ts +32 -1
- package/dist/src/extensions/types/manifest.d.ts +60 -0
- package/dist/src/extensions/types/tui.d.ts +414 -5
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +16 -0
- package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
- package/dist/src/gateway/agent-run-relay.d.ts +2 -3
- package/dist/src/gateway/agent-run-relay.js +10 -3
- package/dist/src/gateway/agent-run-relay.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +32 -19
- package/dist/src/gateway/agents-admin.js +113 -93
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/chat-stream/mapper.d.ts +34 -0
- package/dist/src/gateway/chat-stream/mapper.js +244 -0
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -0
- package/dist/src/gateway/chat-stream/protocol.d.ts +100 -0
- package/dist/src/gateway/chat-stream/protocol.js +1 -0
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/agent-model.d.ts +4 -4
- package/dist/src/gateway/hono/lib/agent-model.js +13 -11
- package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +19 -7
- package/dist/src/gateway/hono/lib/config-payload.js +16 -15
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js +83 -48
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/channels.js +134 -214
- package/dist/src/gateway/hono/routes/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/commands-skills.js +10 -4
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.js +26 -13
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +1 -11
- package/dist/src/gateway/hono/routes/config-patch/channels.js +18 -165
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/config.js +5 -2
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +13 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/public-gateway.js +2 -4
- package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +179 -0
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/tui.d.ts +3 -0
- package/dist/src/gateway/hono/routes/tui.js +16 -0
- package/dist/src/gateway/hono/routes/tui.js.map +1 -0
- package/dist/src/gateway/hono/routes/workflows.js +25 -1
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/sse.d.ts +5 -7
- package/dist/src/gateway/hono/sse.js +21 -38
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/protocol.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +2 -4
- package/dist/src/gateway/service/agent-runner.js +1 -1
- package/dist/src/gateway/service/agent-runner.js.map +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +4 -3
- package/dist/src/gateway/service/marketplace-service.js +7 -4
- package/dist/src/gateway/service/marketplace-service.js.map +1 -1
- package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -6
- package/dist/src/gateway/service/run-gateway-agent.js +63 -36
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +19 -0
- package/dist/src/gateway/service/sessions-api.js +12 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +6 -0
- package/dist/src/gateway/service.js +73 -57
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/project-trust/trust-store.d.ts +30 -0
- package/dist/src/project-trust/trust-store.js +194 -0
- package/dist/src/project-trust/trust-store.js.map +1 -0
- package/dist/src/providers/index.d.ts +1 -1
- package/dist/src/providers/index.js +18 -7
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/routing/resolve-route.d.ts +0 -3
- package/dist/src/routing/resolve-route.js.map +1 -1
- package/dist/src/routing/resolve-tui-session-key.d.ts +2 -0
- package/dist/src/routing/resolve-tui-session-key.js +8 -3
- package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
- package/dist/src/session/client-history.d.ts +32 -0
- package/dist/src/session/client-history.js +232 -1
- package/dist/src/session/client-history.js.map +1 -1
- package/dist/src/session/manager.d.ts +37 -4
- package/dist/src/session/manager.js +39 -15
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/session-context-for-llm.d.ts +93 -1
- package/dist/src/session/session-context-for-llm.js +105 -2
- package/dist/src/session/session-context-for-llm.js.map +1 -1
- package/dist/src/session/store.d.ts +37 -0
- package/dist/src/session/store.js +127 -2
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/stored-rows-to-file-entries.js +37 -1
- package/dist/src/session/stored-rows-to-file-entries.js.map +1 -1
- package/dist/src/session/types.d.ts +14 -1
- package/dist/src/session/types.js.map +1 -1
- package/dist/src/share/share-thumbnail.js +1 -1
- package/dist/src/storage/sqlite/migrations/004_add_session_type_metadata.sql +15 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/row-mappers.d.ts +14 -1
- package/dist/src/storage/sqlite/row-mappers.js +14 -1
- package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/session-metadata.js +1 -0
- package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
- package/dist/src/storage/sqlite/session-repository.js +52 -25
- package/dist/src/storage/sqlite/session-repository.js.map +1 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +53 -4
- package/dist/src/tui/backends/embedded-backend.js +227 -39
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +59 -3
- package/dist/src/tui/backends/gateway-sse-backend.js +416 -26
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/chat-history.d.ts +5 -1
- package/dist/src/tui/chat-history.js +78 -8
- package/dist/src/tui/chat-history.js.map +1 -1
- package/dist/src/tui/clipboard-text.d.ts +5 -0
- package/dist/src/tui/clipboard-text.js +46 -0
- package/dist/src/tui/clipboard-text.js.map +1 -0
- package/dist/src/tui/components/assistant-message.d.ts +19 -3
- package/dist/src/tui/components/assistant-message.js +115 -9
- package/dist/src/tui/components/assistant-message.js.map +1 -1
- package/dist/src/tui/components/bash-execution.d.ts +3 -2
- package/dist/src/tui/components/bash-execution.js +31 -3
- package/dist/src/tui/components/bash-execution.js.map +1 -1
- package/dist/src/tui/components/bash-summary.d.ts +23 -0
- package/dist/src/tui/components/bash-summary.js +87 -0
- package/dist/src/tui/components/bash-summary.js.map +1 -0
- package/dist/src/tui/components/branch-message-summary.d.ts +17 -0
- package/dist/src/tui/components/branch-message-summary.js +43 -0
- package/dist/src/tui/components/branch-message-summary.js.map +1 -0
- package/dist/src/tui/components/branch-summary.d.ts +13 -0
- package/dist/src/tui/components/branch-summary.js +51 -0
- package/dist/src/tui/components/branch-summary.js.map +1 -0
- package/dist/src/tui/components/chat-log.d.ts +46 -6
- package/dist/src/tui/components/chat-log.js +183 -21
- package/dist/src/tui/components/chat-log.js.map +1 -1
- package/dist/src/tui/components/compaction-summary.d.ts +13 -0
- package/dist/src/tui/components/compaction-summary.js +46 -0
- package/dist/src/tui/components/compaction-summary.js.map +1 -0
- package/dist/src/tui/components/custom-editor.d.ts +1 -0
- package/dist/src/tui/components/custom-editor.js +2 -0
- package/dist/src/tui/components/custom-editor.js.map +1 -1
- package/dist/src/tui/components/custom-message.d.ts +23 -0
- package/dist/src/tui/components/custom-message.js +65 -0
- package/dist/src/tui/components/custom-message.js.map +1 -0
- package/dist/src/tui/components/extension-dialog.d.ts +42 -0
- package/dist/src/tui/components/extension-dialog.js +127 -0
- package/dist/src/tui/components/extension-dialog.js.map +1 -0
- package/dist/src/tui/components/scoped-models-selector.d.ts +7 -2
- package/dist/src/tui/components/scoped-models-selector.js +89 -16
- package/dist/src/tui/components/scoped-models-selector.js.map +1 -1
- package/dist/src/tui/components/searchable-select-list.d.ts +30 -3
- package/dist/src/tui/components/searchable-select-list.js +82 -10
- package/dist/src/tui/components/searchable-select-list.js.map +1 -1
- package/dist/src/tui/components/session-selector.d.ts +18 -4
- package/dist/src/tui/components/session-selector.js +207 -40
- package/dist/src/tui/components/session-selector.js.map +1 -1
- package/dist/src/tui/components/settings-selector.d.ts +6 -2
- package/dist/src/tui/components/settings-selector.js +126 -7
- package/dist/src/tui/components/settings-selector.js.map +1 -1
- package/dist/src/tui/components/thinking-selector.d.ts +12 -0
- package/dist/src/tui/components/thinking-selector.js +48 -0
- package/dist/src/tui/components/thinking-selector.js.map +1 -0
- package/dist/src/tui/components/tool-execution.d.ts +57 -3
- package/dist/src/tui/components/tool-execution.js +378 -28
- package/dist/src/tui/components/tool-execution.js.map +1 -1
- package/dist/src/tui/components/tui-bottom-bar.d.ts +9 -1
- package/dist/src/tui/components/tui-bottom-bar.js +56 -11
- package/dist/src/tui/components/tui-bottom-bar.js.map +1 -1
- package/dist/src/tui/components/tui-header.d.ts +9 -2
- package/dist/src/tui/components/tui-header.js +25 -5
- package/dist/src/tui/components/tui-header.js.map +1 -1
- package/dist/src/tui/components/user-message.d.ts +4 -2
- package/dist/src/tui/components/user-message.js +42 -9
- package/dist/src/tui/components/user-message.js.map +1 -1
- package/dist/src/tui/components/visual-truncate.d.ts +11 -0
- package/dist/src/tui/components/visual-truncate.js +27 -0
- package/dist/src/tui/components/visual-truncate.js.map +1 -0
- package/dist/src/tui/extension-host/autocomplete.d.ts +43 -0
- package/dist/src/tui/extension-host/autocomplete.js +116 -0
- package/dist/src/tui/extension-host/autocomplete.js.map +1 -0
- package/dist/src/tui/extension-host/host.d.ts +31 -1
- package/dist/src/tui/extension-host/host.js +123 -6
- package/dist/src/tui/extension-host/host.js.map +1 -1
- package/dist/src/tui/extension-host/load-extensions.d.ts +6 -1
- package/dist/src/tui/extension-host/load-extensions.js +4 -3
- package/dist/src/tui/extension-host/load-extensions.js.map +1 -1
- package/dist/src/tui/extension-host/runtime-context.d.ts +21 -0
- package/dist/src/tui/extension-host/runtime-context.js +152 -0
- package/dist/src/tui/extension-host/runtime-context.js.map +1 -0
- package/dist/src/tui/extension-host/runtime.d.ts +52 -4
- package/dist/src/tui/extension-host/runtime.js +547 -85
- package/dist/src/tui/extension-host/runtime.js.map +1 -1
- package/dist/src/tui/extension-host/surface.d.ts +20 -0
- package/dist/src/tui/extension-host/surface.js +30 -6
- package/dist/src/tui/extension-host/surface.js.map +1 -1
- package/dist/src/tui/extension-host/tool-renderers.d.ts +6 -3
- package/dist/src/tui/extension-host/tool-renderers.js +43 -5
- package/dist/src/tui/extension-host/tool-renderers.js.map +1 -1
- package/dist/src/tui/format-tui-hotkeys.d.ts +12 -2
- package/dist/src/tui/format-tui-hotkeys.js +22 -5
- package/dist/src/tui/format-tui-hotkeys.js.map +1 -1
- package/dist/src/tui/tui-agent-events.d.ts +8 -6
- package/dist/src/tui/tui-agent-events.js +200 -59
- package/dist/src/tui/tui-agent-events.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +169 -3
- package/dist/src/tui/tui-command-formatters.d.ts +76 -0
- package/dist/src/tui/tui-command-formatters.js +594 -0
- package/dist/src/tui/tui-command-formatters.js.map +1 -0
- package/dist/src/tui/tui-commands.d.ts +57 -7
- package/dist/src/tui/tui-commands.js +639 -43
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-context-usage.d.ts +1 -1
- package/dist/src/tui/tui-context-usage.js +9 -1
- package/dist/src/tui/tui-context-usage.js.map +1 -1
- package/dist/src/tui/tui-extension-user-message.d.ts +8 -0
- package/dist/src/tui/tui-extension-user-message.js +32 -0
- package/dist/src/tui/tui-extension-user-message.js.map +1 -0
- package/dist/src/tui/tui-follow-up-queue.d.ts +9 -0
- package/dist/src/tui/tui-follow-up-queue.js +18 -0
- package/dist/src/tui/tui-follow-up-queue.js.map +1 -0
- package/dist/src/tui/tui-local-shell.d.ts +11 -1
- package/dist/src/tui/tui-local-shell.js +50 -8
- package/dist/src/tui/tui-local-shell.js.map +1 -1
- package/dist/src/tui/tui-model-picker.d.ts +26 -0
- package/dist/src/tui/tui-model-picker.js +152 -0
- package/dist/src/tui/tui-model-picker.js.map +1 -0
- package/dist/src/tui/tui-oauth-login.d.ts +16 -0
- package/dist/src/tui/tui-oauth-login.js +189 -0
- package/dist/src/tui/tui-oauth-login.js.map +1 -0
- package/dist/src/tui/tui-overlays.d.ts +3 -3
- package/dist/src/tui/tui-overlays.js +6 -7
- package/dist/src/tui/tui-overlays.js.map +1 -1
- package/dist/src/tui/tui-picker-overlay.d.ts +27 -32
- package/dist/src/tui/tui-picker-overlay.js +340 -30
- package/dist/src/tui/tui-picker-overlay.js.map +1 -1
- package/dist/src/tui/tui-picker-services.d.ts +41 -0
- package/dist/src/tui/tui-picker-services.js +1 -0
- package/dist/src/tui/tui-run-state.d.ts +11 -0
- package/dist/src/tui/tui-run-state.js +114 -0
- package/dist/src/tui/tui-run-state.js.map +1 -0
- package/dist/src/tui/tui-runtime-hints.d.ts +4 -0
- package/dist/src/tui/tui-runtime-hints.js +18 -0
- package/dist/src/tui/tui-runtime-hints.js.map +1 -0
- package/dist/src/tui/tui-scoped-models.d.ts +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-scoped-models.js.map +1 -1
- package/dist/src/tui/tui-session-actions.d.ts +5 -3
- package/dist/src/tui/tui-session-actions.js +21 -9
- package/dist/src/tui/tui-session-actions.js.map +1 -1
- package/dist/src/tui/tui-session-format.d.ts +4 -1
- package/dist/src/tui/tui-session-format.js +17 -3
- package/dist/src/tui/tui-session-format.js.map +1 -1
- package/dist/src/tui/tui-session-snapshot.d.ts +82 -0
- package/dist/src/tui/tui-session-snapshot.js +184 -0
- package/dist/src/tui/tui-session-snapshot.js.map +1 -0
- package/dist/src/tui/tui-session-stats.d.ts +3 -0
- package/dist/src/tui/tui-session-stats.js +59 -0
- package/dist/src/tui/tui-session-stats.js.map +1 -0
- package/dist/src/tui/tui-settings.d.ts +21 -0
- package/dist/src/tui/tui-settings.js +28 -1
- package/dist/src/tui/tui-settings.js.map +1 -1
- package/dist/src/tui/tui-skills-autocomplete.js +1 -1
- package/dist/src/tui/tui-skills-autocomplete.js.map +1 -1
- package/dist/src/tui/tui-startup-resources.d.ts +3 -0
- package/dist/src/tui/tui-startup-resources.js +39 -0
- package/dist/src/tui/tui-startup-resources.js.map +1 -0
- package/dist/src/tui/tui-startup-text.d.ts +10 -0
- package/dist/src/tui/tui-startup-text.js +58 -0
- package/dist/src/tui/tui-startup-text.js.map +1 -0
- package/dist/src/tui/tui-stdio-filter.d.ts +1 -0
- package/dist/src/tui/tui-stdio-filter.js +11 -7
- package/dist/src/tui/tui-stdio-filter.js.map +1 -1
- package/dist/src/tui/tui-submit.d.ts +2 -0
- package/dist/src/tui/tui-submit.js +2 -1
- package/dist/src/tui/tui-submit.js.map +1 -1
- package/dist/src/tui/tui-tool-diff.js +61 -7
- package/dist/src/tui/tui-tool-diff.js.map +1 -1
- package/dist/src/tui/tui-tool-result.d.ts +17 -0
- package/dist/src/tui/tui-tool-result.js +74 -0
- package/dist/src/tui/tui-tool-result.js.map +1 -0
- package/dist/src/tui/tui-transcript-tree-picker.d.ts +57 -0
- package/dist/src/tui/tui-transcript-tree-picker.js +604 -0
- package/dist/src/tui/tui-transcript-tree-picker.js.map +1 -0
- package/dist/src/tui/tui-transcript-tree.d.ts +7 -0
- package/dist/src/tui/tui-transcript-tree.js +316 -0
- package/dist/src/tui/tui-transcript-tree.js.map +1 -0
- package/dist/src/tui/tui-types.d.ts +25 -34
- package/dist/src/tui/tui-types.js +12 -0
- package/dist/src/tui/tui-types.js.map +1 -1
- package/dist/src/tui/tui.js +1288 -112
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/tui/xopc-tui-keybindings.d.ts +127 -2
- package/dist/src/tui/xopc-tui-keybindings.js +127 -2
- package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
- package/dist/src/workflows/domain/definition-utils.d.ts +2 -1
- package/dist/src/workflows/domain/definition-utils.js +18 -8
- package/dist/src/workflows/domain/definition-utils.js.map +1 -1
- package/dist/src/workflows/domain/definition.d.ts +25 -0
- package/dist/src/workflows/domain/event.d.ts +1 -0
- package/dist/src/workflows/domain/result.d.ts +15 -0
- package/dist/src/workflows/domain/run.d.ts +2 -0
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/engine/projector.js +4 -0
- package/dist/src/workflows/engine/projector.js.map +1 -1
- package/dist/src/workflows/engine/workflow-engine.d.ts +37 -1
- package/dist/src/workflows/engine/workflow-engine.js +75 -11
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.d.ts +1 -0
- package/dist/src/workflows/index.js +4 -1
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.d.ts +9 -0
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.js +40 -0
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.js.map +1 -0
- package/dist/src/workflows/registry/index.d.ts +2 -0
- package/dist/src/workflows/registry/index.js +2 -0
- package/dist/src/workflows/registry/workflow-definition-registry.d.ts +15 -0
- package/dist/src/workflows/registry/workflow-definition-registry.js +1 -0
- package/dist/src/workflows/runtime/index.d.ts +2 -0
- package/dist/src/workflows/runtime/index.js +2 -1
- package/dist/src/workflows/runtime/script-workflow-runtime.d.ts +5 -0
- package/dist/src/workflows/runtime/script-workflow-runtime.js +15 -0
- package/dist/src/workflows/runtime/script-workflow-runtime.js.map +1 -0
- package/dist/src/workflows/runtime/workflow-runtime-port.d.ts +16 -0
- package/dist/src/workflows/runtime/workflow-runtime-port.js +1 -0
- package/dist/src/workflows/service/run-view-to-snapshot.js +3 -0
- package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.d.ts +3 -0
- package/dist/src/workflows/service/workflow-run-service.js +10 -15
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +4 -1
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/package.json +21 -15
- package/skills/creative/frontend-design/SKILL.md +1 -1
- package/skills/creative/theme-factory/SKILL.md +1 -1
- package/skills/documents/xlsx/SKILL.md +1 -1
- package/skills/engineering/diagnose/SKILL.md +2 -2
- package/skills/engineering/tdd/SKILL.md +1 -1
- package/skills/tools/github/SKILL.md +6 -1
- package/skills/tools/webapp-testing/SKILL.md +4 -1
- package/dist/extensions/telegram/src/adapters/config-surface.d.ts +0 -2
- package/dist/extensions/telegram/src/adapters/config-surface.js +0 -26
- package/dist/extensions/telegram/src/adapters/config-surface.js.map +0 -1
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +0 -158
- package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +0 -1
- package/dist/gateway/static/root/assets/agents-BwXkia_W.js +0 -222
- package/dist/gateway/static/root/assets/channels-settings-tlOTdaXw.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-D4XjqwqC.js +0 -8
- package/dist/gateway/static/root/assets/cron-api-DcmfGuj0.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-CijJ4G6F.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CyJk_G64.js +0 -1
- package/dist/gateway/static/root/assets/field-primitives-C4GpxsDo.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-config-api-CLD0Gpi3.js +0 -1
- package/dist/gateway/static/root/assets/index-0HmunJW9.js +0 -4845
- package/dist/gateway/static/root/assets/index-Bk75Phrd.css +0 -1
- package/dist/gateway/static/root/assets/notes-page-BBnTh0uI.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-B0riYK7j.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DiP_WHu_.js +0 -2
- package/dist/gateway/static/root/assets/settings-page-1ZPhcCZ9.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-BQ1hllKD.js +0 -2
- package/dist/gateway/static/root/assets/url-F3_D_6zZ.js +0 -3
- package/dist/gateway/static/root/assets/utils-CPr3FBh2.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-BkbDl6dH.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-D059ysoF.js +0 -27
- package/dist/src/agent/embedded/map-stream-events.d.ts +0 -9
- package/dist/src/agent/embedded/map-stream-events.js +0 -63
- package/dist/src/agent/embedded/map-stream-events.js.map +0 -1
- package/dist/src/channels/dock.js.map +0 -1
- package/dist/src/channels/plugins/bundled.d.ts +0 -11
- package/dist/src/channels/plugins/bundled.js +0 -10
- package/dist/src/channels/plugins/bundled.js.map +0 -1
- package/dist/src/channels/registry.d.ts +0 -25
- package/dist/src/channels/registry.js +0 -82
- package/dist/src/channels/registry.js.map +0 -1
- package/dist/src/config/localized-text.d.ts +0 -6
- package/dist/src/config/localized-text.js +0 -42
- package/dist/src/config/localized-text.js.map +0 -1
- package/dist/src/generated/bundled-channel-plugins.d.ts +0 -10
- package/dist/src/generated/bundled-channel-plugins.js +0 -16
- package/dist/src/generated/bundled-channel-plugins.js.map +0 -1
- package/dist/src/tui/stream-assembler.d.ts +0 -22
- package/dist/src/tui/stream-assembler.js +0 -63
- package/dist/src/tui/stream-assembler.js.map +0 -1
- package/skills/browser/SKILL-zh.md +0 -188
- package/skills/business/company-values/SKILL-zh.md +0 -80
- package/skills/business/company-values/SKILL.md +0 -80
- package/skills/business/find-community/SKILL-zh.md +0 -50
- package/skills/business/find-community/SKILL.md +0 -50
- package/skills/business/first-customers/SKILL-zh.md +0 -76
- package/skills/business/first-customers/SKILL.md +0 -76
- package/skills/business/grow-sustainably/SKILL-zh.md +0 -92
- package/skills/business/grow-sustainably/SKILL.md +0 -92
- package/skills/business/marketing-plan/SKILL-zh.md +0 -100
- package/skills/business/marketing-plan/SKILL.md +0 -100
- package/skills/business/minimalist-review/SKILL-zh.md +0 -82
- package/skills/business/minimalist-review/SKILL.md +0 -82
- package/skills/business/mvp/SKILL-zh.md +0 -81
- package/skills/business/mvp/SKILL.md +0 -81
- package/skills/business/pricing/SKILL-zh.md +0 -64
- package/skills/business/pricing/SKILL.md +0 -64
- package/skills/business/processize/SKILL-zh.md +0 -91
- package/skills/business/processize/SKILL.md +0 -91
- package/skills/business/validate-idea/SKILL-zh.md +0 -68
- package/skills/business/validate-idea/SKILL.md +0 -68
- package/skills/creative/algorithmic-art/LICENSE.txt +0 -202
- package/skills/creative/algorithmic-art/SKILL-zh.md +0 -405
- package/skills/creative/algorithmic-art/SKILL.md +0 -405
- package/skills/creative/algorithmic-art/templates/generator_template.js +0 -223
- package/skills/creative/algorithmic-art/templates/viewer.html +0 -599
- package/skills/creative/frontend-design/SKILL-zh.md +0 -42
- package/skills/creative/theme-factory/SKILL-zh.md +0 -59
- package/skills/creative/web-artifacts-builder/LICENSE.txt +0 -202
- package/skills/creative/web-artifacts-builder/SKILL-zh.md +0 -74
- package/skills/creative/web-artifacts-builder/SKILL.md +0 -74
- package/skills/creative/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
- package/skills/creative/web-artifacts-builder/scripts/init-artifact.sh +0 -322
- package/skills/creative/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/documents/doc-coauthoring/SKILL-zh.md +0 -375
- package/skills/documents/doc-coauthoring/SKILL.md +0 -375
- package/skills/documents/docx/LICENSE.txt +0 -30
- package/skills/documents/docx/SKILL-zh.md +0 -590
- package/skills/documents/docx/SKILL.md +0 -590
- package/skills/documents/docx/scripts/__init__.py +0 -1
- package/skills/documents/docx/scripts/accept_changes.py +0 -135
- package/skills/documents/docx/scripts/comment.py +0 -318
- package/skills/documents/docx/scripts/office/helpers/__init__.py +0 -0
- package/skills/documents/docx/scripts/office/helpers/merge_runs.py +0 -199
- package/skills/documents/docx/scripts/office/helpers/simplify_redlines.py +0 -197
- package/skills/documents/docx/scripts/office/pack.py +0 -159
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/skills/documents/docx/scripts/office/schemas/mce/mc.xsd +0 -75
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/skills/documents/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/skills/documents/docx/scripts/office/soffice.py +0 -183
- package/skills/documents/docx/scripts/office/unpack.py +0 -132
- package/skills/documents/docx/scripts/office/validate.py +0 -111
- package/skills/documents/docx/scripts/office/validators/__init__.py +0 -15
- package/skills/documents/docx/scripts/office/validators/base.py +0 -847
- package/skills/documents/docx/scripts/office/validators/docx.py +0 -446
- package/skills/documents/docx/scripts/office/validators/pptx.py +0 -275
- package/skills/documents/docx/scripts/office/validators/redlining.py +0 -247
- package/skills/documents/docx/scripts/templates/comments.xml +0 -3
- package/skills/documents/docx/scripts/templates/commentsExtended.xml +0 -3
- package/skills/documents/docx/scripts/templates/commentsExtensible.xml +0 -3
- package/skills/documents/docx/scripts/templates/commentsIds.xml +0 -3
- package/skills/documents/docx/scripts/templates/people.xml +0 -3
- package/skills/documents/pdf/LICENSE.txt +0 -30
- package/skills/documents/pdf/SKILL-zh.md +0 -314
- package/skills/documents/pdf/SKILL.md +0 -314
- package/skills/documents/pdf/forms.md +0 -294
- package/skills/documents/pdf/reference.md +0 -612
- package/skills/documents/pdf/scripts/check_bounding_boxes.py +0 -65
- package/skills/documents/pdf/scripts/check_fillable_fields.py +0 -11
- package/skills/documents/pdf/scripts/convert_pdf_to_images.py +0 -33
- package/skills/documents/pdf/scripts/create_validation_image.py +0 -37
- package/skills/documents/pdf/scripts/extract_form_field_info.py +0 -122
- package/skills/documents/pdf/scripts/extract_form_structure.py +0 -115
- package/skills/documents/pdf/scripts/fill_fillable_fields.py +0 -98
- package/skills/documents/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
- package/skills/documents/pptx/LICENSE.txt +0 -30
- package/skills/documents/pptx/SKILL-zh.md +0 -232
- package/skills/documents/pptx/SKILL.md +0 -232
- package/skills/documents/pptx/editing.md +0 -205
- package/skills/documents/pptx/pptxgenjs.md +0 -420
- package/skills/documents/pptx/scripts/__init__.py +0 -0
- package/skills/documents/pptx/scripts/add_slide.py +0 -195
- package/skills/documents/pptx/scripts/clean.py +0 -286
- package/skills/documents/pptx/scripts/office/helpers/__init__.py +0 -0
- package/skills/documents/pptx/scripts/office/helpers/merge_runs.py +0 -199
- package/skills/documents/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
- package/skills/documents/pptx/scripts/office/pack.py +0 -159
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/skills/documents/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/skills/documents/pptx/scripts/office/soffice.py +0 -183
- package/skills/documents/pptx/scripts/office/unpack.py +0 -132
- package/skills/documents/pptx/scripts/office/validate.py +0 -111
- package/skills/documents/pptx/scripts/office/validators/__init__.py +0 -15
- package/skills/documents/pptx/scripts/office/validators/base.py +0 -847
- package/skills/documents/pptx/scripts/office/validators/docx.py +0 -446
- package/skills/documents/pptx/scripts/office/validators/pptx.py +0 -275
- package/skills/documents/pptx/scripts/office/validators/redlining.py +0 -247
- package/skills/documents/pptx/scripts/thumbnail.py +0 -289
- package/skills/documents/xlsx/SKILL-zh.md +0 -292
- package/skills/engineering/diagnose/SKILL-zh.md +0 -117
- package/skills/engineering/grill-with-docs/ADR-FORMAT.md +0 -47
- package/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md +0 -77
- package/skills/engineering/grill-with-docs/SKILL-zh.md +0 -88
- package/skills/engineering/grill-with-docs/SKILL.md +0 -88
- package/skills/engineering/improve-codebase-architecture/DEEPENING.md +0 -37
- package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +0 -44
- package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +0 -53
- package/skills/engineering/improve-codebase-architecture/SKILL-zh.md +0 -71
- package/skills/engineering/improve-codebase-architecture/SKILL.md +0 -71
- package/skills/engineering/tdd/SKILL-zh.md +0 -109
- package/skills/engineering/to-issues/SKILL-zh.md +0 -81
- package/skills/engineering/to-issues/SKILL.md +0 -81
- package/skills/engineering/to-prd/SKILL-zh.md +0 -76
- package/skills/engineering/to-prd/SKILL.md +0 -74
- package/skills/engineering/zoom-out/SKILL-zh.md +0 -7
- package/skills/engineering/zoom-out/SKILL.md +0 -7
- package/skills/tools/find-skills/SKILL-zh.md +0 -440
- package/skills/tools/github/SKILL-zh.md +0 -48
- package/skills/tools/internal-comms/LICENSE.txt +0 -202
- package/skills/tools/internal-comms/SKILL-zh.md +0 -32
- package/skills/tools/internal-comms/SKILL.md +0 -32
- package/skills/tools/internal-comms/examples/3p-updates.md +0 -47
- package/skills/tools/internal-comms/examples/company-newsletter.md +0 -65
- package/skills/tools/internal-comms/examples/faq-answers.md +0 -30
- package/skills/tools/internal-comms/examples/general-comms.md +0 -16
- package/skills/tools/skill-creator/LICENSE.txt +0 -202
- package/skills/tools/skill-creator/SKILL-zh.md +0 -483
- package/skills/tools/skill-creator/SKILL.md +0 -485
- package/skills/tools/skill-creator/agents/analyzer.md +0 -274
- package/skills/tools/skill-creator/agents/comparator.md +0 -202
- package/skills/tools/skill-creator/agents/grader.md +0 -223
- package/skills/tools/skill-creator/assets/eval_review.html +0 -146
- package/skills/tools/skill-creator/eval-viewer/generate_review.py +0 -471
- package/skills/tools/skill-creator/eval-viewer/viewer.html +0 -1325
- package/skills/tools/skill-creator/references/schemas.md +0 -430
- package/skills/tools/skill-creator/scripts/__init__.py +0 -0
- package/skills/tools/skill-creator/scripts/aggregate_benchmark.py +0 -401
- package/skills/tools/skill-creator/scripts/generate_report.py +0 -326
- package/skills/tools/skill-creator/scripts/improve_description.py +0 -247
- package/skills/tools/skill-creator/scripts/package_skill.py +0 -136
- package/skills/tools/skill-creator/scripts/quick_validate.py +0 -103
- package/skills/tools/skill-creator/scripts/run_eval.py +0 -310
- package/skills/tools/skill-creator/scripts/run_loop.py +0 -328
- package/skills/tools/skill-creator/scripts/utils.py +0 -47
- package/skills/tools/summarize/SKILL-zh.md +0 -47
- package/skills/tools/weather/SKILL-zh.md +0 -46
- package/skills/tools/weather/SKILL.md +0 -46
- package/skills/tools/webapp-testing/SKILL-zh.md +0 -96
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channels.js","names":[],"sources":["../../../../src/cli/commands/channels.ts"],"sourcesContent":["import { Command } from 'commander';\n\nimport { approveChannelPairingFromCli, type PairingCliChannel } from '../../channels/pairing/index.js';\nimport { resolveConfigPath } from '../../config/paths.js';\nimport {\n getChannelPlugin,\n listChannelPlugins,\n syncChannelPluginsFromManager,\n} from '../../channels/plugins/registry.js';\nimport { bundledChannelPlugins } from '../../generated/bundled-channel-plugins.js';\nimport { loadConfig } from '../../config/loader.js';\nimport type { Config } from '../../config/schema.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { colors } from '../utils/colors.js';\n\nimport {\n SETUP_EXIT,\n SetupValidationError,\n emitOutcome,\n isPromptCancelled,\n promptSecret,\n runSetup,\n type SetupOutcome,\n} from './setup-shared/index.js';\n\nfunction ensureChannelRegistryForCli(): void {\n if (listChannelPlugins().length === 0) {\n syncChannelPluginsFromManager(bundledChannelPlugins);\n }\n}\n\nfunction resolveConfigPathFromCommand(command: Command): string {\n const root =\n command.parent?.parent && command.parent.parent instanceof Command\n ? command.parent.parent\n : command.parent && command.parent instanceof Command\n ? command.parent\n : null;\n const globalOpts = (root && typeof root.opts === 'function'\n ? (root.opts() as { config?: string })\n : {}) as { config?: string };\n return (\n globalOpts.config?.trim() ||\n process.env.XOPC_CONFIG_PATH?.trim() ||\n process.env.XOPC_CONFIG?.trim() ||\n resolveConfigPath()\n );\n}\n\nfunction createChannelsCommand(ctx: CLIContext): Command {\n const cmd = new Command('channels')\n .description('Messaging channel login and credentials')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc channels login',\n 'xopc channels login --channel weixin',\n 'xopc channels login --channel feishu',\n 'xopc channels login --account my-bot-id',\n 'xopc channels pairing approve --channel telegram ABC12XYZ',\n ]),\n );\n\n const PAIRING_CHANNELS = new Set<PairingCliChannel>(['telegram', 'feishu', 'weixin']);\n\n cmd\n .command('login')\n .description('Log in with QR code or channel-specific credentials flow')\n .option(\n '--channel <id>',\n 'Channel id (auto-detected when only one login-capable channel is registered)',\n )\n .option('--account <id>', 'Optional account id when re-logging an existing bot')\n .option('--timeout <ms>', 'Max wait for scan (default 480000)', '480000')\n .option('--credentials-only', 'Only save token files; do not update xopc.json')\n .action(async (options, command) => {\n ensureChannelRegistryForCli();\n const explicitChannel = options.channel?.trim?.();\n let channelId: string;\n if (explicitChannel) {\n channelId = explicitChannel;\n } else {\n const loginCapable = listChannelPlugins().filter((p) => p.cliLogin);\n if (loginCapable.length === 1) {\n channelId = loginCapable[0].id;\n console.log(`Auto-detected channel: ${channelId}`);\n } else if (loginCapable.length === 0) {\n console.error('No channels with login support found.');\n process.exitCode = 1;\n return;\n } else {\n console.error(\n `Multiple channels support login: ${loginCapable.map((p) => p.id).join(', ')}. ` +\n 'Use --channel <id> to specify.',\n );\n process.exitCode = 1;\n return;\n }\n }\n const plugin = getChannelPlugin(channelId);\n if (!plugin?.cliLogin) {\n console.error(`Channel \"${channelId}\" does not support CLI login.`);\n const capable = listChannelPlugins()\n .filter((p) => p.cliLogin)\n .map((p) => p.id);\n if (capable.length > 0) {\n console.error(`Channels with login support: ${capable.join(', ')}`);\n }\n process.exitCode = 1;\n return;\n }\n\n const configPath = resolveConfigPathFromCommand(command);\n const timeoutMs = Math.max(60_000, Number.parseInt(String(options.timeout), 10) || 480_000);\n const verbose = ctx.isVerbose;\n\n const result = await plugin.cliLogin.runLogin({\n configPath,\n verbose,\n timeoutMs,\n accountId: options.account?.trim() || undefined,\n writeConfig: !options.credentialsOnly,\n });\n\n if (!result.ok) {\n if (result.cancelled) {\n process.exitCode = 130;\n return;\n }\n console.error(result.message || 'Login failed');\n process.exitCode = 1;\n }\n });\n\n cmd\n .command('list')\n .description('List configured channels and their account status')\n .option('--json', 'Output as JSON for agents/UIs', false)\n .action((opts: { json?: boolean }) => {\n ensureChannelRegistryForCli();\n const cfg = loadConfig(resolveConfigPathFromCommand(cmd));\n const channelsCfg = (cfg.channels ?? {}) as Record<string, Record<string, unknown>>;\n const entries = listChannelPlugins().map((plugin) => {\n const raw = channelsCfg[plugin.id] ?? {};\n const enabled = raw.enabled === true;\n const accounts = (raw.accounts ?? {}) as Record<string, Record<string, unknown>>;\n const accountSummaries = Object.entries(accounts).map(([id, acct]) => ({\n accountId: id,\n enabled: acct.enabled !== false,\n configured: typeof acct.botToken === 'string'\n ? Boolean((acct.botToken as string).trim())\n : false,\n }));\n return {\n id: plugin.id,\n name: plugin.meta?.label ?? plugin.id,\n enabled,\n hasLogin: Boolean(plugin.cliLogin),\n accountCount: accountSummaries.length,\n accounts: accountSummaries,\n };\n });\n if (opts.json) {\n process.stdout.write(JSON.stringify({ ok: true, channels: entries }) + '\\n');\n return;\n }\n console.log('');\n console.log(colors.bold('CHANNELS'));\n const idWidth = Math.max(...entries.map((e) => e.id.length));\n for (const e of entries) {\n const status = e.enabled\n ? colors.green('● enabled')\n : colors.gray('○ disabled');\n const accts = e.accountCount > 0 ? colors.gray(` (${e.accountCount} accounts)`) : '';\n console.log(` ${e.id.padEnd(idWidth)} ${status} ${colors.gray(e.name)}${accts}`);\n }\n console.log('');\n console.log(colors.gray('Use: xopc channels add <id> [--token <token>]'));\n });\n\n cmd\n .command('add <channel>')\n .description('Add or update a channel account (currently: telegram)')\n .option('--token <value>', 'Bot token (Telegram). Prompts securely if omitted.')\n .option('--account <id>', 'Account id (default: \"default\")')\n .option('--enable', 'Enable the channel after writing (default: true)', true)\n .option('--dry-run', 'Show the change without writing', false)\n .option('--json', 'Emit a single JSON outcome line', false)\n .action(\n async (\n channel: string,\n opts: {\n token?: string;\n account?: string;\n enable?: boolean;\n dryRun?: boolean;\n json?: boolean;\n },\n ) => {\n const channelId = channel.trim().toLowerCase();\n const accountId = opts.account?.trim() || 'default';\n const dryRun = Boolean(opts.dryRun);\n const json = Boolean(opts.json);\n\n if (channelId === 'feishu' || channelId === 'weixin') {\n const outcome: SetupOutcome = {\n ok: false,\n action: 'add',\n domain: `channels.${channelId}`,\n target: accountId,\n changedPaths: [],\n dryRun,\n errors: [\n {\n message:\n channelId === 'weixin'\n ? 'Weixin uses interactive QR login. Run: xopc channels login --channel weixin'\n : 'Feishu add via CLI is not yet implemented. Edit `~/.xopc/xopc.json` (channels.feishu) or run: xopc onboard --channels',\n },\n ],\n };\n emitOutcome(outcome, json);\n process.exitCode = SETUP_EXIT.ERROR;\n return;\n }\n\n if (channelId !== 'telegram') {\n const outcome: SetupOutcome = {\n ok: false,\n action: 'add',\n domain: `channels.${channelId}`,\n target: accountId,\n changedPaths: [],\n dryRun,\n errors: [{ message: `Unknown channel \"${channelId}\". Try: xopc channels list` }],\n };\n emitOutcome(outcome, json);\n process.exitCode = SETUP_EXIT.ERROR;\n return;\n }\n\n let token = opts.token?.trim();\n if (!token) {\n token = process.env.TELEGRAM_BOT_TOKEN?.trim();\n }\n if (!token) {\n try {\n token = await promptSecret('Telegram bot token (from @BotFather):');\n } catch (error) {\n if (isPromptCancelled(error)) {\n const outcome: SetupOutcome = {\n ok: false,\n action: 'add',\n domain: 'channels.telegram',\n target: accountId,\n changedPaths: [],\n dryRun,\n errors: [{ message: 'Cancelled by user' }],\n };\n emitOutcome(outcome, json);\n process.exitCode = SETUP_EXIT.CANCELLED;\n return;\n }\n throw error;\n }\n }\n\n if (!validateTelegramToken(token)) {\n const outcome: SetupOutcome = {\n ok: false,\n action: 'add',\n domain: 'channels.telegram',\n target: accountId,\n changedPaths: [],\n dryRun,\n errors: [{ path: 'token', message: 'Token does not look like a Telegram bot token (expected `<digits>:<35+ chars>`).' }],\n };\n emitOutcome(outcome, json);\n process.exitCode = SETUP_EXIT.ERROR;\n return;\n }\n\n await runSetup({\n configPath: resolveConfigPathFromCommand(cmd),\n options: { dryRun, json },\n mutator: {\n domain: 'channels.telegram',\n target: accountId,\n action: 'add',\n mutate(config) {\n return applyTelegramAccount(config, accountId, token!, opts.enable !== false);\n },\n resultValue: () => ({\n channel: 'telegram',\n accountId,\n tokenMask: maskToken(token!),\n }),\n notes: () => [\n opts.enable !== false\n ? 'Telegram channel enabled. Restart the gateway for the new bot to come online.'\n : 'Telegram credentials saved (channel disabled). Use `--enable` to start it.',\n ],\n },\n });\n },\n );\n\n cmd\n .command('remove <channel>')\n .description('Remove a channel account')\n .option('--account <id>', 'Account id (default: \"default\")')\n .option('--dry-run', 'Show the change without writing', false)\n .option('--json', 'Emit a single JSON outcome line', false)\n .action(\n async (\n channel: string,\n opts: { account?: string; dryRun?: boolean; json?: boolean },\n ) => {\n const channelId = channel.trim().toLowerCase();\n const accountId = opts.account?.trim() || 'default';\n const dryRun = Boolean(opts.dryRun);\n const json = Boolean(opts.json);\n\n await runSetup({\n configPath: resolveConfigPathFromCommand(cmd),\n options: { dryRun, json },\n mutator: {\n domain: `channels.${channelId}`,\n target: accountId,\n action: 'remove',\n mutate(config) {\n return removeChannelAccount(config, channelId, accountId);\n },\n },\n });\n },\n );\n\n cmd\n .command('schema [channel]')\n .description('Print credential schemas for channels (for agents / UIs)')\n .option('--json', 'JSON output (default human-readable JSON)', false)\n .action((channel: string | undefined, opts: { json?: boolean }) => {\n ensureChannelRegistryForCli();\n const all = listChannelPlugins().map((p) => ({\n id: p.id,\n name: p.meta?.label ?? p.id,\n hasLogin: Boolean(p.cliLogin),\n configSchema: p.configSchema?.schema,\n }));\n const payload = {\n ok: true,\n channels: channel ? all.filter((c) => c.id === channel) : all,\n };\n if (opts.json) {\n process.stdout.write(JSON.stringify(payload) + '\\n');\n } else {\n console.log(JSON.stringify(payload, null, 2));\n }\n });\n\n cmd\n .command('pairing')\n .description('Approve DM pairing requests (updates channel allowFrom credential files)')\n .addCommand(\n new Command('approve')\n .description('Approve a pairing code shown to the user in Telegram / Feishu / Weixin DMs')\n .requiredOption('--channel <id>', 'telegram | feishu | weixin')\n .option('--account <id>', 'Bot account id from config', 'default')\n .argument('<code>', 'Pairing code from the user message')\n .action((code: string, options: { channel?: string; account?: string }) => {\n const ch = (options.channel ?? '').trim().toLowerCase() as PairingCliChannel;\n if (!PAIRING_CHANNELS.has(ch)) {\n console.error('Invalid --channel. Use: telegram, feishu, or weixin.');\n process.exitCode = 1;\n return;\n }\n const accountId = (options.account ?? 'default').trim() || 'default';\n const result = approveChannelPairingFromCli({\n channel: ch,\n accountId,\n code: String(code ?? '').trim(),\n });\n if (result.ok === false) {\n console.error(result.error);\n process.exitCode = 1;\n return;\n }\n console.log(`Approved. Sender id added to allowFrom store: ${result.senderId}`);\n }),\n );\n\n return cmd;\n}\n\n// ---------- helpers ----------\n\nconst TELEGRAM_TOKEN_PATTERN = /^\\d{5,}:[A-Za-z0-9_-]{30,}$/;\n\nexport function validateTelegramToken(token: string): boolean {\n return TELEGRAM_TOKEN_PATTERN.test(token.trim());\n}\n\nexport function maskToken(token: string): string {\n const t = token.trim();\n if (t.length <= 8) return '*'.repeat(t.length);\n return `${t.slice(0, 4)}…${t.slice(-4)}`;\n}\n\nexport function applyTelegramAccount(\n cfg: Config,\n accountId: string,\n botToken: string,\n enable: boolean,\n): Config {\n const channels = { ...((cfg.channels ?? {}) as Record<string, unknown>) };\n const tg = { ...((channels.telegram ?? {}) as Record<string, unknown>) };\n if (enable) tg.enabled = true;\n const accounts = { ...((tg.accounts ?? {}) as Record<string, Record<string, unknown>>) };\n accounts[accountId] = {\n ...(accounts[accountId] ?? {}),\n accountId,\n enabled: true,\n botToken,\n };\n tg.accounts = accounts;\n channels.telegram = tg;\n return { ...cfg, channels } as Config;\n}\n\nexport function removeChannelAccount(\n cfg: Config,\n channelId: string,\n accountId: string,\n): Config {\n if (channelId === 'feishu' || channelId === 'weixin' || channelId === 'telegram') {\n const channels = { ...((cfg.channels ?? {}) as Record<string, unknown>) };\n const ch = { ...((channels[channelId] ?? {}) as Record<string, unknown>) };\n const accounts = { ...((ch.accounts ?? {}) as Record<string, unknown>) };\n if (!(accountId in accounts)) {\n throw new SetupValidationError([\n { message: `No account \"${accountId}\" on channel \"${channelId}\".` },\n ]);\n }\n delete accounts[accountId];\n ch.accounts = accounts;\n if (Object.keys(accounts).length === 0) {\n ch.enabled = false;\n }\n channels[channelId] = ch;\n return { ...cfg, channels } as Config;\n }\n throw new SetupValidationError([\n { message: `Unknown channel \"${channelId}\". Try: xopc channels list` },\n ]);\n}\n\nregister({\n id: 'channels',\n name: 'channels',\n description: 'Messaging channel login',\n factory: createChannelsCommand,\n metadata: {\n category: 'setup',\n examples: [\n 'xopc channels list',\n 'xopc channels add telegram --token 123456:ABC...',\n 'xopc channels remove telegram',\n 'xopc channels login',\n 'xopc channels pairing approve --channel feishu --account default ABC12XYZ',\n ],\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"channels.js","names":[],"sources":["../../../../src/cli/commands/channels.ts"],"sourcesContent":["import { Command } from 'commander';\n\nimport {\n approveChannelPairingFromCli,\n listChannelPairingState,\n} from '../../channels/pairing/index.js';\nimport { buildChannelCatalogForConfig } from '../../channels/catalog/channel-catalog-service.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport type { Config } from '../../config/schema.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { colors } from '../utils/colors.js';\n\nfunction normalizeChannelId(raw: string): string {\n return raw.trim().toLowerCase();\n}\n\nfunction loadCliConfig(ctx: CLIContext): Config {\n return loadConfig(ctx.configPath);\n}\n\nasync function writeCliConfig(ctx: CLIContext, cfg: Config): Promise<void> {\n await saveConfig(cfg, ctx.configPath);\n}\n\nfunction ensureChannelObject(cfg: Config, channelId: string): Record<string, unknown> {\n if (!cfg.channels) cfg.channels = {};\n const channels = cfg.channels as Record<string, unknown>;\n const existing = channels[channelId];\n if (existing && typeof existing === 'object' && !Array.isArray(existing)) {\n return existing as Record<string, unknown>;\n }\n const next: Record<string, unknown> = {};\n channels[channelId] = next;\n return next;\n}\n\nfunction assertCatalogChannel(cfg: Config, channelId: string): void {\n const catalog = buildChannelCatalogForConfig(cfg);\n if (!catalog.byId.has(channelId)) {\n throw new Error(`Unknown channel \"${channelId}\". Install or declare a channel extension contribution first.`);\n }\n}\n\nfunction createChannelsCommand(ctx: CLIContext): Command {\n const cmd = new Command('channels')\n .description('Messaging channel configuration')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc channels list',\n 'xopc channels show telegram',\n 'xopc channels enable telegram',\n 'xopc channels config set-json telegram \\'{\"enabled\":true}\\'',\n 'xopc channels pairing approve telegram ABC12XYZ',\n ]),\n );\n\n cmd\n .command('list')\n .description('List channel extension contributions')\n .option('--json', 'Output as JSON', false)\n .action((opts: { json?: boolean }) => {\n const cfg = loadCliConfig(ctx);\n const catalog = buildChannelCatalogForConfig(cfg);\n const channels = cfg.channels as Record<string, { enabled?: boolean } | undefined> | undefined;\n const rows = catalog.entries.map((entry) => ({\n id: entry.id,\n label: entry.label,\n extensionId: entry.extensionId,\n source: entry.source,\n enabled: channels?.[entry.id]?.enabled === true,\n configured: Boolean(channels?.[entry.id]),\n }));\n if (opts.json) {\n process.stdout.write(`${JSON.stringify({ ok: true, channels: rows })}\\n`);\n return;\n }\n console.log('');\n console.log(colors.bold('CHANNELS'));\n const idWidth = Math.max(2, ...rows.map((r) => r.id.length));\n for (const row of rows) {\n const status = row.enabled ? colors.green('enabled') : colors.gray('disabled');\n console.log(` ${row.id.padEnd(idWidth)} ${status} ${colors.gray(row.label)} ${colors.gray(row.extensionId)}`);\n }\n console.log('');\n });\n\n cmd\n .command('show <channel>')\n .description('Show one channel catalog entry and config')\n .option('--json', 'Output as JSON', false)\n .action((channel: string, opts: { json?: boolean }) => {\n const cfg = loadCliConfig(ctx);\n const channelId = normalizeChannelId(channel);\n const catalog = buildChannelCatalogForConfig(cfg);\n const entry = catalog.byId.get(channelId);\n if (!entry) {\n console.error(`Unknown channel \"${channelId}\".`);\n process.exitCode = 1;\n return;\n }\n const config = (cfg.channels as Record<string, unknown> | undefined)?.[channelId] ?? {};\n const payload = { entry, config };\n if (opts.json) {\n process.stdout.write(`${JSON.stringify({ ok: true, ...payload })}\\n`);\n return;\n }\n console.log(JSON.stringify(payload, null, 2));\n });\n\n cmd\n .command('enable <channel>')\n .description('Enable a channel config block')\n .action(async (channel: string) => {\n const cfg = loadCliConfig(ctx);\n const channelId = normalizeChannelId(channel);\n assertCatalogChannel(cfg, channelId);\n ensureChannelObject(cfg, channelId).enabled = true;\n await writeCliConfig(ctx, cfg);\n console.log(`Enabled channel ${channelId}`);\n });\n\n cmd\n .command('disable <channel>')\n .description('Disable a channel config block')\n .action(async (channel: string) => {\n const cfg = loadCliConfig(ctx);\n const channelId = normalizeChannelId(channel);\n assertCatalogChannel(cfg, channelId);\n ensureChannelObject(cfg, channelId).enabled = false;\n await writeCliConfig(ctx, cfg);\n console.log(`Disabled channel ${channelId}`);\n });\n\n const config = cmd.command('config').description('Edit channel config');\n config\n .command('set-json <channel> <json>')\n .description('Merge a JSON object into channels.<id>')\n .action(async (channel: string, json: string) => {\n const cfg = loadCliConfig(ctx);\n const channelId = normalizeChannelId(channel);\n assertCatalogChannel(cfg, channelId);\n const patch = JSON.parse(json) as unknown;\n if (!patch || typeof patch !== 'object' || Array.isArray(patch)) {\n throw new Error('JSON value must be an object');\n }\n Object.assign(ensureChannelObject(cfg, channelId), patch);\n await writeCliConfig(ctx, cfg);\n console.log(`Updated channels.${channelId}`);\n });\n\n const pairing = cmd.command('pairing').description('Manage channel pairing state');\n pairing\n .command('list <channel>')\n .option('--account <id>', 'Account id', 'default')\n .option('--json', 'Output as JSON', false)\n .action((channel: string, opts: { account?: string; json?: boolean }) => {\n const cfg = loadCliConfig(ctx);\n const state = listChannelPairingState({\n channel: normalizeChannelId(channel),\n accountId: opts.account,\n config: cfg,\n });\n if (opts.json) {\n process.stdout.write(`${JSON.stringify({ ok: true, state })}\\n`);\n return;\n }\n console.log(JSON.stringify(state, null, 2));\n });\n pairing\n .command('approve <channel> <code>')\n .option('--account <id>', 'Account id', 'default')\n .action((channel: string, code: string, opts: { account?: string }) => {\n const result = approveChannelPairingFromCli({\n channel: normalizeChannelId(channel),\n accountId: opts.account ?? 'default',\n code,\n });\n if (result.ok === false) {\n console.error(result.error);\n process.exitCode = 1;\n return;\n }\n console.log(`Approved sender ${result.senderId}`);\n });\n\n return cmd;\n}\n\nregister({\n id: 'channels',\n name: 'channels',\n description: 'Messaging channel configuration',\n factory: createChannelsCommand,\n metadata: {\n category: 'setup',\n examples: [\n 'xopc channels list',\n 'xopc channels show telegram',\n 'xopc channels enable telegram',\n 'xopc channels config set-json telegram \\'{\"enabled\":true}\\'',\n ],\n },\n});\n"],"mappings":"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"}
|
|
@@ -75,7 +75,7 @@ function setNestedValue(obj, path, value) {
|
|
|
75
75
|
}
|
|
76
76
|
function createConfigCommand(ctx) {
|
|
77
77
|
const cmd = new Command("config").description("View and edit configuration").option("--show", "Show full configuration (alias for `config show`)").option("--validate", "Validate configuration file (alias for `config validate`)").addHelpText("after", formatExamples([
|
|
78
|
-
"xopc config get agents.defaults.
|
|
78
|
+
"xopc config get agents.defaults.models.chat",
|
|
79
79
|
"xopc config set agents.defaults.temperature 0.8",
|
|
80
80
|
"xopc config unset agents.defaults.max_tokens",
|
|
81
81
|
"xopc config show",
|
|
@@ -205,7 +205,7 @@ register({
|
|
|
205
205
|
metadata: {
|
|
206
206
|
category: "utility",
|
|
207
207
|
examples: [
|
|
208
|
-
"xopc config get agents.defaults.
|
|
208
|
+
"xopc config get agents.defaults.models.chat",
|
|
209
209
|
"xopc config set agents.defaults.temperature 0.8",
|
|
210
210
|
"xopc config show",
|
|
211
211
|
"xopc config validate",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":[],"sources":["../../../../src/cli/commands/config.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { existsSync, readFileSync } from 'fs';\nimport { resolveGatewayLocalClientHost } from '../../config/gateway-bind.js';\nimport { writeTextAtomic } from '../../infra/write-file-atomic.js';\nimport { ConfigSchema } from '../../config/schema.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nconst MISSING_CONFIG_HINT = 'Run: xopc setup, xopc onboard, or xopc init';\n\nasync function loadConfigDeps() {\n const [{ loadConfig }, { createLogger }] = await Promise.all([\n import('../../config/index.js'),\n import('../../utils/logger.js'),\n ]);\n return { loadConfig, log: createLogger('ConfigCommand') };\n}\n\nasync function runConfigShow(configPath: string): Promise<void> {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(configPath)) {\n log.warn(`No config file found. ${MISSING_CONFIG_HINT}`);\n return;\n }\n\n const config = loadConfig(configPath);\n const maskedConfig = JSON.stringify(\n config,\n (key, value) => {\n if (key === 'api_key' || key === 'token') {\n return value ? '********' : value;\n }\n return value;\n },\n 2,\n );\n console.log(maskedConfig);\n}\n\nasync function runConfigValidate(configPath: string): Promise<boolean> {\n const { log } = await loadConfigDeps();\n if (!existsSync(configPath)) {\n log.error('Config file not found. Run: xopc onboard');\n return false;\n }\n\n let json: unknown;\n try {\n json = JSON.parse(readFileSync(configPath, 'utf-8'));\n } catch {\n log.error('Config file is not valid JSON.');\n return false;\n }\n\n const parsed = ConfigSchema.safeParse(json);\n if (!parsed.success) {\n log.error('Config does not match the expected schema.');\n for (const issue of parsed.error.issues) {\n console.error(` - ${issue.path.join('.') || '(root)'}: ${issue.message}`);\n }\n return false;\n }\n\n const { validateChannelPluginConfigs } = await import('../../config/validate-channel-configs.js');\n const channelErrors = validateChannelPluginConfigs(parsed.data);\n if (channelErrors.length > 0) {\n log.error('Channel configuration failed validation.');\n for (const err of channelErrors) {\n console.error(` - ${err}`);\n }\n return false;\n }\n\n log.info({ path: configPath }, 'Config is valid');\n console.log('✅ Configuration is valid');\n return true;\n}\n\nfunction getNestedValue(obj: any, path: string): any {\n return path.split('.').reduce((current: any, key: string) => {\n if (current && typeof current === 'object' && key in current) {\n return current[key];\n }\n return undefined;\n }, obj);\n}\n\nfunction setNestedValue(obj: any, path: string, value: any): any {\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n const target = keys.reduce((current: any, key: string) => {\n if (!current[key] || typeof current[key] !== 'object') {\n current[key] = {};\n }\n return current[key];\n }, obj);\n target[lastKey] = value;\n return obj;\n}\n\nfunction createConfigCommand(ctx: CLIContext): Command {\n const cmd = new Command('config')\n .description('View and edit configuration')\n .option('--show', 'Show full configuration (alias for `config show`)')\n .option('--validate', 'Validate configuration file (alias for `config validate`)')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc config get agents.defaults.model',\n 'xopc config set agents.defaults.temperature 0.8',\n 'xopc config unset agents.defaults.max_tokens',\n 'xopc config show',\n 'xopc config validate',\n 'xopc config token # Show gateway token info',\n 'xopc config token --show # Show full token',\n 'xopc config token --generate # Generate new token',\n ]),\n )\n .action(async (options) => {\n if (options.show) {\n await runConfigShow(ctx.configPath);\n return;\n }\n if (options.validate) {\n const ok = await runConfigValidate(ctx.configPath);\n if (!ok) {\n process.exit(1);\n }\n return;\n }\n cmd.outputHelp();\n });\n\n cmd\n .command('get <path>')\n .description('Get a config value by dot path')\n .action(async (path: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n const value = getNestedValue(config, path);\n\n if (value === undefined) {\n log.error({ path }, `Config path not found`);\n process.exit(1);\n }\n\n console.log(typeof value === 'object' ? JSON.stringify(value, null, 2) : value);\n });\n\n cmd\n .command('set <path> <value>')\n .description('Set a config value by dot path')\n .action(async (path: string, value: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n let parsedValue: any;\n try {\n parsedValue = JSON.parse(value);\n } catch {\n parsedValue = value;\n }\n\n const config = loadConfig(ctx.configPath);\n setNestedValue(config, path, parsedValue);\n\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n\n log.info({ path }, `Config updated`);\n });\n\n cmd\n .command('unset <path>')\n .description('Remove a config value by dot path')\n .action(async (path: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n const target = keys.reduce((current: any, key: string) => {\n return current && current[key];\n }, config);\n\n if (target && typeof target === 'object' && lastKey in target) {\n delete target[lastKey];\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n log.info({ path }, `Config removed`);\n } else {\n log.error({ path }, `Config path not found`);\n process.exit(1);\n }\n });\n\n cmd\n .command('show')\n .description('Show full configuration (sensitive values masked)')\n .action(async () => {\n await runConfigShow(ctx.configPath);\n });\n\n cmd\n .command('validate')\n .description('Validate configuration file against schema and channel plugins')\n .action(async () => {\n const ok = await runConfigValidate(ctx.configPath);\n if (!ok) {\n process.exit(1);\n }\n });\n\n cmd\n .command('token')\n .description('Generate or view the gateway auth token')\n .option('--generate', 'Generate a new token')\n .option('--show', 'Show the current token (unmasked)')\n .action(async (options) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n\n if (options.show) {\n const token = config?.gateway?.auth?.token;\n if (token) {\n console.log(token);\n } else {\n console.log('No token configured. Gateway auth mode:', config?.gateway?.auth?.mode || 'not set');\n }\n return;\n }\n\n if (options.generate) {\n const crypto = await import('crypto');\n const newToken = crypto.randomBytes(24).toString('hex');\n\n config.gateway = config.gateway || {};\n config.gateway.auth = {\n mode: 'token',\n token: newToken,\n };\n\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n log.info('New gateway token generated');\n console.log(`Token: ${newToken.slice(0, 8)}...${newToken.slice(-8)}`);\n console.log('\\nUse \"xopc config token --show\" to view the full token');\n return;\n }\n\n // Default: show masked token info\n const token = config?.gateway?.auth?.token;\n const mode = config?.gateway?.auth?.mode;\n const bind = config?.gateway?.bind ?? 'loopback';\n const port = config?.gateway?.port || 18790;\n const clientHost = config ? resolveGatewayLocalClientHost(config) : '127.0.0.1';\n\n console.log('Gateway Configuration:');\n console.log(` Bind: ${bind}`);\n console.log(` Local URL: http://${clientHost}:${port}`);\n console.log(` Auth Mode: ${mode || 'not set'}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n console.log('\\nUse \"xopc config token --show\" to view the full token');\n console.log('Use \"xopc config token --generate\" to generate a new token');\n } else if (mode === 'token') {\n console.log(' Token: not set (will be auto-generated on first `xopc gateway` run)');\n }\n });\n\n cmd\n .command('path')\n .description('Show configuration file path')\n .action(() => {\n console.log(ctx.configPath);\n });\n\n return cmd;\n}\n\nregister({\n id: 'config',\n name: 'config',\n description: 'View and edit configuration',\n factory: createConfigCommand,\n metadata: {\n category: 'utility',\n examples: [\n 'xopc config get agents.defaults.model',\n 'xopc config set agents.defaults.temperature 0.8',\n 'xopc config show',\n 'xopc config validate',\n 'xopc config token',\n 'xopc config token --show',\n 'xopc config token --generate',\n ],\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../../../../src/cli/commands/config.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { existsSync, readFileSync } from 'fs';\nimport { resolveGatewayLocalClientHost } from '../../config/gateway-bind.js';\nimport { writeTextAtomic } from '../../infra/write-file-atomic.js';\nimport { ConfigSchema } from '../../config/schema.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nconst MISSING_CONFIG_HINT = 'Run: xopc setup, xopc onboard, or xopc init';\n\nasync function loadConfigDeps() {\n const [{ loadConfig }, { createLogger }] = await Promise.all([\n import('../../config/index.js'),\n import('../../utils/logger.js'),\n ]);\n return { loadConfig, log: createLogger('ConfigCommand') };\n}\n\nasync function runConfigShow(configPath: string): Promise<void> {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(configPath)) {\n log.warn(`No config file found. ${MISSING_CONFIG_HINT}`);\n return;\n }\n\n const config = loadConfig(configPath);\n const maskedConfig = JSON.stringify(\n config,\n (key, value) => {\n if (key === 'api_key' || key === 'token') {\n return value ? '********' : value;\n }\n return value;\n },\n 2,\n );\n console.log(maskedConfig);\n}\n\nasync function runConfigValidate(configPath: string): Promise<boolean> {\n const { log } = await loadConfigDeps();\n if (!existsSync(configPath)) {\n log.error('Config file not found. Run: xopc onboard');\n return false;\n }\n\n let json: unknown;\n try {\n json = JSON.parse(readFileSync(configPath, 'utf-8'));\n } catch {\n log.error('Config file is not valid JSON.');\n return false;\n }\n\n const parsed = ConfigSchema.safeParse(json);\n if (!parsed.success) {\n log.error('Config does not match the expected schema.');\n for (const issue of parsed.error.issues) {\n console.error(` - ${issue.path.join('.') || '(root)'}: ${issue.message}`);\n }\n return false;\n }\n\n const { validateChannelPluginConfigs } = await import('../../config/validate-channel-configs.js');\n const channelErrors = validateChannelPluginConfigs(parsed.data);\n if (channelErrors.length > 0) {\n log.error('Channel configuration failed validation.');\n for (const err of channelErrors) {\n console.error(` - ${err}`);\n }\n return false;\n }\n\n log.info({ path: configPath }, 'Config is valid');\n console.log('✅ Configuration is valid');\n return true;\n}\n\nfunction getNestedValue(obj: any, path: string): any {\n return path.split('.').reduce((current: any, key: string) => {\n if (current && typeof current === 'object' && key in current) {\n return current[key];\n }\n return undefined;\n }, obj);\n}\n\nfunction setNestedValue(obj: any, path: string, value: any): any {\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n const target = keys.reduce((current: any, key: string) => {\n if (!current[key] || typeof current[key] !== 'object') {\n current[key] = {};\n }\n return current[key];\n }, obj);\n target[lastKey] = value;\n return obj;\n}\n\nfunction createConfigCommand(ctx: CLIContext): Command {\n const cmd = new Command('config')\n .description('View and edit configuration')\n .option('--show', 'Show full configuration (alias for `config show`)')\n .option('--validate', 'Validate configuration file (alias for `config validate`)')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc config get agents.defaults.models.chat',\n 'xopc config set agents.defaults.temperature 0.8',\n 'xopc config unset agents.defaults.max_tokens',\n 'xopc config show',\n 'xopc config validate',\n 'xopc config token # Show gateway token info',\n 'xopc config token --show # Show full token',\n 'xopc config token --generate # Generate new token',\n ]),\n )\n .action(async (options) => {\n if (options.show) {\n await runConfigShow(ctx.configPath);\n return;\n }\n if (options.validate) {\n const ok = await runConfigValidate(ctx.configPath);\n if (!ok) {\n process.exit(1);\n }\n return;\n }\n cmd.outputHelp();\n });\n\n cmd\n .command('get <path>')\n .description('Get a config value by dot path')\n .action(async (path: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n const value = getNestedValue(config, path);\n\n if (value === undefined) {\n log.error({ path }, `Config path not found`);\n process.exit(1);\n }\n\n console.log(typeof value === 'object' ? JSON.stringify(value, null, 2) : value);\n });\n\n cmd\n .command('set <path> <value>')\n .description('Set a config value by dot path')\n .action(async (path: string, value: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n let parsedValue: any;\n try {\n parsedValue = JSON.parse(value);\n } catch {\n parsedValue = value;\n }\n\n const config = loadConfig(ctx.configPath);\n setNestedValue(config, path, parsedValue);\n\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n\n log.info({ path }, `Config updated`);\n });\n\n cmd\n .command('unset <path>')\n .description('Remove a config value by dot path')\n .action(async (path: string) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n const target = keys.reduce((current: any, key: string) => {\n return current && current[key];\n }, config);\n\n if (target && typeof target === 'object' && lastKey in target) {\n delete target[lastKey];\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n log.info({ path }, `Config removed`);\n } else {\n log.error({ path }, `Config path not found`);\n process.exit(1);\n }\n });\n\n cmd\n .command('show')\n .description('Show full configuration (sensitive values masked)')\n .action(async () => {\n await runConfigShow(ctx.configPath);\n });\n\n cmd\n .command('validate')\n .description('Validate configuration file against schema and channel plugins')\n .action(async () => {\n const ok = await runConfigValidate(ctx.configPath);\n if (!ok) {\n process.exit(1);\n }\n });\n\n cmd\n .command('token')\n .description('Generate or view the gateway auth token')\n .option('--generate', 'Generate a new token')\n .option('--show', 'Show the current token (unmasked)')\n .action(async (options) => {\n const { loadConfig, log } = await loadConfigDeps();\n if (!existsSync(ctx.configPath)) {\n log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);\n process.exit(1);\n }\n\n const config = loadConfig(ctx.configPath);\n\n if (options.show) {\n const token = config?.gateway?.auth?.token;\n if (token) {\n console.log(token);\n } else {\n console.log('No token configured. Gateway auth mode:', config?.gateway?.auth?.mode || 'not set');\n }\n return;\n }\n\n if (options.generate) {\n const crypto = await import('crypto');\n const newToken = crypto.randomBytes(24).toString('hex');\n\n config.gateway = config.gateway || {};\n config.gateway.auth = {\n mode: 'token',\n token: newToken,\n };\n\n await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));\n log.info('New gateway token generated');\n console.log(`Token: ${newToken.slice(0, 8)}...${newToken.slice(-8)}`);\n console.log('\\nUse \"xopc config token --show\" to view the full token');\n return;\n }\n\n // Default: show masked token info\n const token = config?.gateway?.auth?.token;\n const mode = config?.gateway?.auth?.mode;\n const bind = config?.gateway?.bind ?? 'loopback';\n const port = config?.gateway?.port || 18790;\n const clientHost = config ? resolveGatewayLocalClientHost(config) : '127.0.0.1';\n\n console.log('Gateway Configuration:');\n console.log(` Bind: ${bind}`);\n console.log(` Local URL: http://${clientHost}:${port}`);\n console.log(` Auth Mode: ${mode || 'not set'}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n console.log('\\nUse \"xopc config token --show\" to view the full token');\n console.log('Use \"xopc config token --generate\" to generate a new token');\n } else if (mode === 'token') {\n console.log(' Token: not set (will be auto-generated on first `xopc gateway` run)');\n }\n });\n\n cmd\n .command('path')\n .description('Show configuration file path')\n .action(() => {\n console.log(ctx.configPath);\n });\n\n return cmd;\n}\n\nregister({\n id: 'config',\n name: 'config',\n description: 'View and edit configuration',\n factory: createConfigCommand,\n metadata: {\n category: 'utility',\n examples: [\n 'xopc config get agents.defaults.models.chat',\n 'xopc config set agents.defaults.temperature 0.8',\n 'xopc config show',\n 'xopc config validate',\n 'xopc config token',\n 'xopc config token --show',\n 'xopc config token --generate',\n ],\n },\n});\n"],"mappings":"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"}
|
|
@@ -1,62 +1,11 @@
|
|
|
1
|
+
import { buildChannelCatalogForConfig, init_channel_catalog_service } from "../../../../channels/catalog/channel-catalog-service.js";
|
|
1
2
|
import { init_loader, loadConfig } from "../../../../config/loader.js";
|
|
2
3
|
import { existsSync } from "node:fs";
|
|
3
4
|
//#region src/cli/commands/doctor/checks/channel-config.ts
|
|
5
|
+
init_channel_catalog_service();
|
|
4
6
|
init_loader();
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
if (!tg) return {
|
|
8
|
-
ok: true,
|
|
9
|
-
messages: [],
|
|
10
|
-
hints: []
|
|
11
|
-
};
|
|
12
|
-
const defaultAcc = tg.accounts?.default;
|
|
13
|
-
const token = defaultAcc?.botToken?.trim() ?? "";
|
|
14
|
-
if (!(tg.enabled === true || token.length > 0)) return {
|
|
15
|
-
ok: true,
|
|
16
|
-
messages: [],
|
|
17
|
-
hints: []
|
|
18
|
-
};
|
|
19
|
-
const messages = [];
|
|
20
|
-
const hints = [];
|
|
21
|
-
if (!token) {
|
|
22
|
-
messages.push("Telegram is enabled but no bot token is set.");
|
|
23
|
-
hints.push("Set channels.telegram.accounts.default.botToken.");
|
|
24
|
-
}
|
|
25
|
-
const dm = (defaultAcc?.dmPolicy ?? tg.dmPolicy) || "pairing";
|
|
26
|
-
if (![
|
|
27
|
-
"pairing",
|
|
28
|
-
"allowlist",
|
|
29
|
-
"open",
|
|
30
|
-
"disabled"
|
|
31
|
-
].includes(dm)) messages.push(`Telegram dmPolicy "${dm}" is not valid.`);
|
|
32
|
-
if (dm === "open") {
|
|
33
|
-
messages.push("Telegram DM policy is \"open\" (any user can message the bot).");
|
|
34
|
-
hints.push("Consider \"pairing\" or \"allowlist\" for stricter access.");
|
|
35
|
-
}
|
|
36
|
-
return {
|
|
37
|
-
ok: messages.length === 0,
|
|
38
|
-
messages,
|
|
39
|
-
hints
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
function checkWeixin(cfg) {
|
|
43
|
-
const wx = cfg.channels?.weixin;
|
|
44
|
-
if (!wx || wx.enabled !== true) return {
|
|
45
|
-
ok: true,
|
|
46
|
-
messages: [],
|
|
47
|
-
hints: []
|
|
48
|
-
};
|
|
49
|
-
const messages = [];
|
|
50
|
-
const hints = [];
|
|
51
|
-
if ((wx.accounts ? Object.keys(wx.accounts).filter((k) => k.trim()) : []).length === 0) {
|
|
52
|
-
messages.push("Weixin is enabled but no accounts are defined in config.");
|
|
53
|
-
hints.push("Run: xopc channels login --channel weixin (or add channels.weixin.accounts).");
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
ok: messages.length === 0,
|
|
57
|
-
messages,
|
|
58
|
-
hints
|
|
59
|
-
};
|
|
7
|
+
function isEnabledChannelConfig(value) {
|
|
8
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && value.enabled === true;
|
|
60
9
|
}
|
|
61
10
|
async function checkChannelConfig(ctx) {
|
|
62
11
|
if (!existsSync(ctx.configPath)) return {
|
|
@@ -78,32 +27,30 @@ async function checkChannelConfig(ctx) {
|
|
|
78
27
|
hints: []
|
|
79
28
|
};
|
|
80
29
|
}
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
const allHints = [...tg.hints, ...wx.hints];
|
|
85
|
-
const tgEnabled = (cfg.channels?.telegram)?.enabled === true || Boolean((cfg.channels?.telegram)?.accounts?.default?.botToken?.trim());
|
|
86
|
-
const wxOn = (cfg.channels?.weixin)?.enabled === true;
|
|
87
|
-
if (!tgEnabled && !wxOn) return {
|
|
30
|
+
const channels = cfg.channels;
|
|
31
|
+
const enabledIds = Object.entries(channels ?? {}).filter(([, value]) => isEnabledChannelConfig(value)).map(([id]) => id);
|
|
32
|
+
if (enabledIds.length === 0) return {
|
|
88
33
|
id: "channel-config",
|
|
89
34
|
label: "Channels",
|
|
90
35
|
status: "skip",
|
|
91
36
|
message: "No channels enabled; skipped.",
|
|
92
37
|
hints: []
|
|
93
38
|
};
|
|
94
|
-
|
|
39
|
+
const catalog = buildChannelCatalogForConfig(cfg);
|
|
40
|
+
const unknownIds = enabledIds.filter((id) => !catalog.byId.has(id));
|
|
41
|
+
if (unknownIds.length > 0) return {
|
|
95
42
|
id: "channel-config",
|
|
96
43
|
label: "Channels",
|
|
97
|
-
status: "
|
|
98
|
-
message:
|
|
99
|
-
hints: []
|
|
44
|
+
status: "fail",
|
|
45
|
+
message: `Enabled channel(s) are not declared by installed extensions: ${unknownIds.join(", ")}.`,
|
|
46
|
+
hints: ["Install or enable an extension that declares each channel contribution."]
|
|
100
47
|
};
|
|
101
48
|
return {
|
|
102
49
|
id: "channel-config",
|
|
103
50
|
label: "Channels",
|
|
104
|
-
status:
|
|
105
|
-
message:
|
|
106
|
-
hints:
|
|
51
|
+
status: "pass",
|
|
52
|
+
message: `Enabled channel configuration loaded for: ${enabledIds.join(", ")}.`,
|
|
53
|
+
hints: []
|
|
107
54
|
};
|
|
108
55
|
}
|
|
109
56
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-config.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/channel-config.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport { loadConfig } from '../../../../config/loader.js';\nimport type { Config } from '../../../../config/schema.js';\nimport type { CheckResult, DoctorContext } from '../types.js';\n\
|
|
1
|
+
{"version":3,"file":"channel-config.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/channel-config.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport { buildChannelCatalogForConfig } from '../../../../channels/catalog/channel-catalog-service.js';\nimport { loadConfig } from '../../../../config/loader.js';\nimport type { Config } from '../../../../config/schema.js';\nimport type { CheckResult, DoctorContext } from '../types.js';\n\nfunction isEnabledChannelConfig(value: unknown): value is { enabled: true } {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && (value as { enabled?: unknown }).enabled === true;\n}\n\nexport async function checkChannelConfig(ctx: DoctorContext): Promise<CheckResult> {\n if (!existsSync(ctx.configPath)) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'skip',\n message: 'No config file; skipped.',\n hints: [],\n };\n }\n\n let cfg: Config;\n try {\n cfg = loadConfig(ctx.configPath);\n } catch {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'skip',\n message: 'Config could not be loaded; skipped.',\n hints: [],\n };\n }\n\n const channels = cfg.channels as Record<string, unknown> | undefined;\n const enabledIds = Object.entries(channels ?? {})\n .filter(([, value]) => isEnabledChannelConfig(value))\n .map(([id]) => id);\n\n if (enabledIds.length === 0) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'skip',\n message: 'No channels enabled; skipped.',\n hints: [],\n };\n }\n\n const catalog = buildChannelCatalogForConfig(cfg);\n const unknownIds = enabledIds.filter((id) => !catalog.byId.has(id));\n if (unknownIds.length > 0) {\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'fail',\n message: `Enabled channel(s) are not declared by installed extensions: ${unknownIds.join(', ')}.`,\n hints: ['Install or enable an extension that declares each channel contribution.'],\n };\n }\n\n return {\n id: 'channel-config',\n label: 'Channels',\n status: 'pass',\n message: `Enabled channel configuration loaded for: ${enabledIds.join(', ')}.`,\n hints: [],\n };\n}\n"],"mappings":";;;;8BAEuG;aAC7C;AAI1D,SAAS,uBAAuB,OAA4C;AAC1E,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM,IAAK,MAAgC,YAAY;;AAG9H,eAAsB,mBAAmB,KAA0C;AACjF,KAAI,CAAC,WAAW,IAAI,WAAW,CAC7B,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,IAAI;AACJ,KAAI;AACF,QAAM,WAAW,IAAI,WAAW;SAC1B;AACN,SAAO;GACL,IAAI;GACJ,OAAO;GACP,QAAQ;GACR,SAAS;GACT,OAAO,EAAE;GACV;;CAGH,MAAM,WAAW,IAAI;CACrB,MAAM,aAAa,OAAO,QAAQ,YAAY,EAAE,CAAC,CAC9C,QAAQ,GAAG,WAAW,uBAAuB,MAAM,CAAC,CACpD,KAAK,CAAC,QAAQ,GAAG;AAEpB,KAAI,WAAW,WAAW,EACxB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,MAAM,UAAU,6BAA6B,IAAI;CACjD,MAAM,aAAa,WAAW,QAAQ,OAAO,CAAC,QAAQ,KAAK,IAAI,GAAG,CAAC;AACnE,KAAI,WAAW,SAAS,EACtB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,gEAAgE,WAAW,KAAK,KAAK,CAAC;EAC/F,OAAO,CAAC,0EAA0E;EACnF;AAGH,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,6CAA6C,WAAW,KAAK,KAAK,CAAC;EAC5E,OAAO,EAAE;EACV"}
|
|
@@ -3,8 +3,10 @@ import { collectPairingPendingIssues } from "../../../../channels/pairing/pairin
|
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
//#region src/cli/commands/doctor/checks/channel-pairing-pending.ts
|
|
5
5
|
init_loader();
|
|
6
|
-
function
|
|
7
|
-
return (cfg.channels
|
|
6
|
+
function hasEnabledChannel(cfg) {
|
|
7
|
+
return Object.values(cfg.channels ?? {}).some((value) => {
|
|
8
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && value.enabled === true;
|
|
9
|
+
});
|
|
8
10
|
}
|
|
9
11
|
async function checkChannelPairingPending(ctx) {
|
|
10
12
|
if (!existsSync(ctx.configPath)) return {
|
|
@@ -26,7 +28,7 @@ async function checkChannelPairingPending(ctx) {
|
|
|
26
28
|
hints: []
|
|
27
29
|
};
|
|
28
30
|
}
|
|
29
|
-
if (!(
|
|
31
|
+
if (!hasEnabledChannel(cfg)) return {
|
|
30
32
|
id: "channel-pairing-pending",
|
|
31
33
|
label: "Channel pairing",
|
|
32
34
|
status: "skip",
|
|
@@ -47,7 +49,7 @@ async function checkChannelPairingPending(ctx) {
|
|
|
47
49
|
const parts = [`${totalPending} pending pairing request(s) across enabled channels.`];
|
|
48
50
|
if (totalStale > 0) parts.push(`${totalStale} pending over 30 minutes (codes expire after 1 hour).`);
|
|
49
51
|
if (atCapacity.length > 0) parts.push(`${atCapacity.length} account(s) at the pending limit — approve or wait for expiry before new users can request codes.`);
|
|
50
|
-
const hints = ["Approve in the gateway console under Settings → Channels, or run: xopc channels pairing approve
|
|
52
|
+
const hints = ["Approve in the gateway console under Settings → Channels, or run: xopc channels pairing approve <id> <CODE>"];
|
|
51
53
|
if (totalStale > 0) hints.push("Stale requests may expire soon; ask users to send a fresh DM if approval fails.");
|
|
52
54
|
return {
|
|
53
55
|
id: "channel-pairing-pending",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-pairing-pending.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/channel-pairing-pending.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport { collectPairingPendingIssues } from '../../../../channels/pairing/pairing-service.js';\nimport { loadConfig } from '../../../../config/loader.js';\nimport type { Config } from '../../../../config/schema.js';\nimport type { CheckResult, DoctorContext } from '../types.js';\n\nfunction
|
|
1
|
+
{"version":3,"file":"channel-pairing-pending.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/channel-pairing-pending.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport { collectPairingPendingIssues } from '../../../../channels/pairing/pairing-service.js';\nimport { loadConfig } from '../../../../config/loader.js';\nimport type { Config } from '../../../../config/schema.js';\nimport type { CheckResult, DoctorContext } from '../types.js';\n\nfunction hasEnabledChannel(cfg: Config): boolean {\n return Object.values(cfg.channels ?? {}).some((value) => {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && (value as { enabled?: unknown }).enabled === true;\n });\n}\n\nexport async function checkChannelPairingPending(ctx: DoctorContext): Promise<CheckResult> {\n if (!existsSync(ctx.configPath)) {\n return {\n id: 'channel-pairing-pending',\n label: 'Channel pairing',\n status: 'skip',\n message: 'No config file; skipped.',\n hints: [],\n };\n }\n\n let cfg: Config;\n try {\n cfg = loadConfig(ctx.configPath);\n } catch {\n return {\n id: 'channel-pairing-pending',\n label: 'Channel pairing',\n status: 'skip',\n message: 'Config could not be loaded; skipped.',\n hints: [],\n };\n }\n\n if (!hasEnabledChannel(cfg)) {\n return {\n id: 'channel-pairing-pending',\n label: 'Channel pairing',\n status: 'skip',\n message: 'No channels enabled; skipped.',\n hints: [],\n };\n }\n\n const issues = collectPairingPendingIssues(cfg);\n if (issues.length === 0) {\n return {\n id: 'channel-pairing-pending',\n label: 'Channel pairing',\n status: 'pass',\n message: 'No pending DM pairing requests.',\n hints: [],\n };\n }\n\n const totalPending = issues.reduce((n, i) => n + i.pending, 0);\n const totalStale = issues.reduce((n, i) => n + i.stale, 0);\n const atCapacity = issues.filter((i) => i.atCapacity);\n\n const parts: string[] = [\n `${totalPending} pending pairing request(s) across enabled channels.`,\n ];\n if (totalStale > 0) {\n parts.push(`${totalStale} pending over 30 minutes (codes expire after 1 hour).`);\n }\n if (atCapacity.length > 0) {\n parts.push(\n `${atCapacity.length} account(s) at the pending limit — approve or wait for expiry before new users can request codes.`,\n );\n }\n\n const hints = [\n 'Approve in the gateway console under Settings → Channels, or run: xopc channels pairing approve <id> <CODE>',\n ];\n if (totalStale > 0) {\n hints.push('Stale requests may expire soon; ask users to send a fresh DM if approval fails.');\n }\n\n return {\n id: 'channel-pairing-pending',\n label: 'Channel pairing',\n status: 'warn',\n message: parts.join(' '),\n hints,\n };\n}\n"],"mappings":";;;;aAG0D;AAI1D,SAAS,kBAAkB,KAAsB;AAC/C,QAAO,OAAO,OAAO,IAAI,YAAY,EAAE,CAAC,CAAC,MAAM,UAAU;AACvD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM,IAAK,MAAgC,YAAY;GAC5H;;AAGJ,eAAsB,2BAA2B,KAA0C;AACzF,KAAI,CAAC,WAAW,IAAI,WAAW,CAC7B,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,IAAI;AACJ,KAAI;AACF,QAAM,WAAW,IAAI,WAAW;SAC1B;AACN,SAAO;GACL,IAAI;GACJ,OAAO;GACP,QAAQ;GACR,SAAS;GACT,OAAO,EAAE;GACV;;AAGH,KAAI,CAAC,kBAAkB,IAAI,CACzB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,MAAM,SAAS,4BAA4B,IAAI;AAC/C,KAAI,OAAO,WAAW,EACpB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,MAAM,eAAe,OAAO,QAAQ,GAAG,MAAM,IAAI,EAAE,SAAS,EAAE;CAC9D,MAAM,aAAa,OAAO,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,EAAE;CAC1D,MAAM,aAAa,OAAO,QAAQ,MAAM,EAAE,WAAW;CAErD,MAAM,QAAkB,CACtB,GAAG,aAAa,sDACjB;AACD,KAAI,aAAa,EACf,OAAM,KAAK,GAAG,WAAW,uDAAuD;AAElF,KAAI,WAAW,SAAS,EACtB,OAAM,KACJ,GAAG,WAAW,OAAO,mGACtB;CAGH,MAAM,QAAQ,CACZ,8GACD;AACD,KAAI,aAAa,EACf,OAAM,KAAK,kFAAkF;AAG/F,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS,MAAM,KAAK,IAAI;EACxB;EACD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { init_loader, loadConfig } from "../../../../config/loader.js";
|
|
2
|
-
import {
|
|
2
|
+
import { listChannelPlugins } from "../../../../channels/plugins/registry.js";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
//#region src/cli/commands/doctor/checks/channel-plugins.ts
|
|
5
5
|
init_loader();
|
|
@@ -22,7 +22,7 @@ async function checkChannelPlugins(ctx) {
|
|
|
22
22
|
return [];
|
|
23
23
|
}
|
|
24
24
|
const out = [];
|
|
25
|
-
for (const plugin of
|
|
25
|
+
for (const plugin of listChannelPlugins()) {
|
|
26
26
|
const doctor = plugin.doctor;
|
|
27
27
|
if (!doctor?.check) continue;
|
|
28
28
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-plugins.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/channel-plugins.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport type { CheckResult, DoctorContext } from '../types.js';\nimport { loadConfig } from '../../../../config/loader.js';\nimport {
|
|
1
|
+
{"version":3,"file":"channel-plugins.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/channel-plugins.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport type { CheckResult, DoctorContext } from '../types.js';\nimport { loadConfig } from '../../../../config/loader.js';\nimport { listChannelPlugins } from '../../../../channels/plugins/registry.js';\nimport type { ChannelDoctorCheckResult, ChannelPlugin } from '../../../../channels/plugin-types.js';\n\nfunction toCheckResults(plugin: ChannelPlugin, raw: ChannelDoctorCheckResult[]): CheckResult[] {\n const pid = String(plugin.id);\n return raw.map((r) => ({\n id: `channel:${pid}:${r.id}`,\n label: `${pid}: ${r.label}`,\n status: r.status,\n message: r.message,\n hints: r.hints,\n }));\n}\n\nexport async function checkChannelPlugins(ctx: DoctorContext): Promise<CheckResult[]> {\n if (!existsSync(ctx.configPath)) {\n return [];\n }\n\n let cfg;\n try {\n cfg = loadConfig(ctx.configPath);\n } catch {\n return [];\n }\n\n const out: CheckResult[] = [];\n for (const plugin of listChannelPlugins()) {\n const doctor = plugin.doctor;\n if (!doctor?.check) continue;\n try {\n const res = await doctor.check({ cfg });\n out.push(...toCheckResults(plugin, res));\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n out.push({\n id: `channel:${plugin.id}:error`,\n label: `${String(plugin.id)}: doctor`,\n status: 'warn',\n message: `Channel doctor check failed: ${msg}`,\n hints: [],\n });\n }\n }\n return out;\n}\n"],"mappings":";;;;aAG0D;AAI1D,SAAS,eAAe,QAAuB,KAAgD;CAC7F,MAAM,MAAM,OAAO,OAAO,GAAG;AAC7B,QAAO,IAAI,KAAK,OAAO;EACrB,IAAI,WAAW,IAAI,GAAG,EAAE;EACxB,OAAO,GAAG,IAAI,IAAI,EAAE;EACpB,QAAQ,EAAE;EACV,SAAS,EAAE;EACX,OAAO,EAAE;EACV,EAAE;;AAGL,eAAsB,oBAAoB,KAA4C;AACpF,KAAI,CAAC,WAAW,IAAI,WAAW,CAC7B,QAAO,EAAE;CAGX,IAAI;AACJ,KAAI;AACF,QAAM,WAAW,IAAI,WAAW;SAC1B;AACN,SAAO,EAAE;;CAGX,MAAM,MAAqB,EAAE;AAC7B,MAAK,MAAM,UAAU,oBAAoB,EAAE;EACzC,MAAM,SAAS,OAAO;AACtB,MAAI,CAAC,QAAQ,MAAO;AACpB,MAAI;GACF,MAAM,MAAM,MAAM,OAAO,MAAM,EAAE,KAAK,CAAC;AACvC,OAAI,KAAK,GAAG,eAAe,QAAQ,IAAI,CAAC;WACjC,GAAG;GACV,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,OAAI,KAAK;IACP,IAAI,WAAW,OAAO,GAAG;IACzB,OAAO,GAAG,OAAO,OAAO,GAAG,CAAC;IAC5B,QAAQ;IACR,SAAS,gCAAgC;IACzC,OAAO,EAAE;IACV,CAAC;;;AAGN,QAAO"}
|
|
@@ -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 v4).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -14,18 +14,22 @@ function collectProviderIdsFromConfig(cfg) {
|
|
|
14
14
|
if (parsed) ids.add(parsed.provider.toLowerCase());
|
|
15
15
|
};
|
|
16
16
|
addRef(getAgentDefaultModelRef(cfg));
|
|
17
|
-
const
|
|
18
|
-
|
|
17
|
+
const addModelConfig = (raw) => {
|
|
18
|
+
addRef(raw?.primary);
|
|
19
|
+
if (Array.isArray(raw?.fallbacks)) for (const f of raw.fallbacks) addRef(typeof f === "string" ? f : void 0);
|
|
20
|
+
};
|
|
21
|
+
const addRoles = (roles) => {
|
|
22
|
+
for (const role of Object.values(roles ?? {})) addRef(role.model);
|
|
23
|
+
};
|
|
24
|
+
addModelConfig(cfg.agents?.defaults?.models?.chat);
|
|
25
|
+
addRoles(cfg.agents?.defaults?.models?.roles);
|
|
19
26
|
const list = cfg.agents?.list;
|
|
20
27
|
if (Array.isArray(list)) for (const e of list) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
else if (m && typeof m === "object" && "primary" in m) {
|
|
24
|
-
addRef(typeof m.primary === "string" ? m.primary : void 0);
|
|
25
|
-
const fb = m.fallbacks;
|
|
26
|
-
if (Array.isArray(fb)) for (const f of fb) addRef(f);
|
|
27
|
-
}
|
|
28
|
+
addModelConfig(e?.models?.chat);
|
|
29
|
+
addRoles(e?.models?.roles);
|
|
28
30
|
}
|
|
31
|
+
const raw = cfg.agents?.defaults?.imageModel;
|
|
32
|
+
if (raw && typeof raw === "object" && "fallbacks" in raw && Array.isArray(raw.fallbacks)) for (const f of raw.fallbacks) addRef(typeof f === "string" ? f : void 0);
|
|
29
33
|
const img = cfg.agents?.defaults?.imageModel;
|
|
30
34
|
if (typeof img === "string") addRef(img);
|
|
31
35
|
else if (img && typeof img === "object" && "primary" in img) addRef(typeof img.primary === "string" ? img.primary : void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-auth.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/provider-auth.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport { loadConfig } from '../../../../config/loader.js';\nimport type { Config } from '../../../../config/schema.js';\nimport { parseModelRef, getAgentDefaultModelRef } from '../../../../config/schema.js';\nimport { getApiKeyFromEnv, PROVIDER_ENV_MAP } from '../../../../providers/env-keys.js';\nimport type { CheckResult, DoctorContext } from '../types.js';\n\nfunction collectProviderIdsFromConfig(cfg: Config): Set<string> {\n const ids = new Set<string>();\n\n const addRef = (ref: string | undefined) => {\n if (!ref?.trim()) return;\n const parsed = parseModelRef(ref.trim());\n if (parsed) ids.add(parsed.provider.toLowerCase());\n };\n\n addRef(getAgentDefaultModelRef(cfg));\n\n const
|
|
1
|
+
{"version":3,"file":"provider-auth.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/provider-auth.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\n\nimport { loadConfig } from '../../../../config/loader.js';\nimport type { Config } from '../../../../config/schema.js';\nimport { parseModelRef, getAgentDefaultModelRef } from '../../../../config/schema.js';\nimport { getApiKeyFromEnv, PROVIDER_ENV_MAP } from '../../../../providers/env-keys.js';\nimport type { CheckResult, DoctorContext } from '../types.js';\n\nfunction collectProviderIdsFromConfig(cfg: Config): Set<string> {\n const ids = new Set<string>();\n\n const addRef = (ref: string | undefined) => {\n if (!ref?.trim()) return;\n const parsed = parseModelRef(ref.trim());\n if (parsed) ids.add(parsed.provider.toLowerCase());\n };\n\n addRef(getAgentDefaultModelRef(cfg));\n\n const addModelConfig = (raw: { primary?: string; fallbacks?: string[] } | undefined) => {\n addRef(raw?.primary);\n if (Array.isArray(raw?.fallbacks)) {\n for (const f of raw.fallbacks) {\n addRef(typeof f === 'string' ? f : undefined);\n }\n }\n };\n const addRoles = (roles: Record<string, { model?: string }> | undefined) => {\n for (const role of Object.values(roles ?? {})) {\n addRef(role.model);\n }\n };\n\n addModelConfig(cfg.agents?.defaults?.models?.chat);\n addRoles(cfg.agents?.defaults?.models?.roles);\n\n const list = cfg.agents?.list;\n if (Array.isArray(list)) {\n for (const e of list) {\n addModelConfig(e?.models?.chat);\n addRoles(e?.models?.roles);\n }\n }\n\n const raw = cfg.agents?.defaults?.imageModel;\n if (raw && typeof raw === 'object' && 'fallbacks' in raw && Array.isArray(raw.fallbacks)) {\n for (const f of raw.fallbacks) {\n addRef(typeof f === 'string' ? f : undefined);\n }\n }\n\n const img = cfg.agents?.defaults?.imageModel;\n if (typeof img === 'string') addRef(img);\n else if (img && typeof img === 'object' && 'primary' in img) {\n addRef(typeof img.primary === 'string' ? img.primary : undefined);\n }\n\n const ss = cfg.agents?.defaults?.sessionSearch?.summaryModel;\n if (typeof ss === 'string') addRef(ss);\n\n return ids;\n}\n\nfunction anyProviderEnvPresent(): boolean {\n for (const vars of Object.values(PROVIDER_ENV_MAP)) {\n for (const v of vars) {\n if (process.env[v]?.trim()) return true;\n }\n }\n for (const [k, val] of Object.entries(process.env)) {\n if (!val?.trim()) continue;\n if (k.endsWith('_API_KEY') || k.endsWith('_TOKEN')) return true;\n }\n return false;\n}\n\nexport async function checkProviderAuth(ctx: DoctorContext): Promise<CheckResult> {\n if (!existsSync(ctx.configPath)) {\n return {\n id: 'provider-auth',\n label: 'Provider auth',\n status: 'skip',\n message: 'No config file; skipped.',\n hints: [],\n };\n }\n\n let cfg: Config;\n try {\n cfg = loadConfig(ctx.configPath);\n } catch {\n return {\n id: 'provider-auth',\n label: 'Provider auth',\n status: 'skip',\n message: 'Config could not be loaded; skipped.',\n hints: [],\n };\n }\n\n const fromConfig = collectProviderIdsFromConfig(cfg);\n const checkIds = fromConfig.size > 0 ? [...fromConfig] : Object.keys(PROVIDER_ENV_MAP);\n\n for (const id of checkIds) {\n const key = getApiKeyFromEnv(id);\n if (key?.trim()) {\n return {\n id: 'provider-auth',\n label: 'Provider auth',\n status: 'pass',\n message: 'At least one LLM provider API key is available.',\n hints: [],\n };\n }\n }\n\n if (anyProviderEnvPresent()) {\n return {\n id: 'provider-auth',\n label: 'Provider auth',\n status: 'pass',\n message: 'Environment contains provider credentials.',\n hints: [],\n };\n }\n\n return {\n id: 'provider-auth',\n label: 'Provider auth',\n status: 'warn',\n message: 'No API keys detected for configured providers.',\n hints: ['Set keys via: xopc auth set <provider> <key>', 'Or export the provider env vars from the pi-ai docs.'],\n };\n}\n"],"mappings":";;;;;aAE0D;aAE4B;eACC;AAGvF,SAAS,6BAA6B,KAA0B;CAC9D,MAAM,sBAAM,IAAI,KAAa;CAE7B,MAAM,UAAU,QAA4B;AAC1C,MAAI,CAAC,KAAK,MAAM,CAAE;EAClB,MAAM,SAAS,cAAc,IAAI,MAAM,CAAC;AACxC,MAAI,OAAQ,KAAI,IAAI,OAAO,SAAS,aAAa,CAAC;;AAGpD,QAAO,wBAAwB,IAAI,CAAC;CAEpC,MAAM,kBAAkB,QAAgE;AACtF,SAAO,KAAK,QAAQ;AACpB,MAAI,MAAM,QAAQ,KAAK,UAAU,CAC/B,MAAK,MAAM,KAAK,IAAI,UAClB,QAAO,OAAO,MAAM,WAAW,IAAI,KAAA,EAAU;;CAInD,MAAM,YAAY,UAA0D;AAC1E,OAAK,MAAM,QAAQ,OAAO,OAAO,SAAS,EAAE,CAAC,CAC3C,QAAO,KAAK,MAAM;;AAItB,gBAAe,IAAI,QAAQ,UAAU,QAAQ,KAAK;AAClD,UAAS,IAAI,QAAQ,UAAU,QAAQ,MAAM;CAE7C,MAAM,OAAO,IAAI,QAAQ;AACzB,KAAI,MAAM,QAAQ,KAAK,CACrB,MAAK,MAAM,KAAK,MAAM;AACpB,iBAAe,GAAG,QAAQ,KAAK;AAC/B,WAAS,GAAG,QAAQ,MAAM;;CAI9B,MAAM,MAAM,IAAI,QAAQ,UAAU;AAClC,KAAI,OAAO,OAAO,QAAQ,YAAY,eAAe,OAAO,MAAM,QAAQ,IAAI,UAAU,CACtF,MAAK,MAAM,KAAK,IAAI,UAClB,QAAO,OAAO,MAAM,WAAW,IAAI,KAAA,EAAU;CAIjD,MAAM,MAAM,IAAI,QAAQ,UAAU;AAClC,KAAI,OAAO,QAAQ,SAAU,QAAO,IAAI;UAC/B,OAAO,OAAO,QAAQ,YAAY,aAAa,IACtD,QAAO,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU,KAAA,EAAU;CAGnE,MAAM,KAAK,IAAI,QAAQ,UAAU,eAAe;AAChD,KAAI,OAAO,OAAO,SAAU,QAAO,GAAG;AAEtC,QAAO;;AAGT,SAAS,wBAAiC;AACxC,MAAK,MAAM,QAAQ,OAAO,OAAO,iBAAiB,CAChD,MAAK,MAAM,KAAK,KACd,KAAI,QAAQ,IAAI,IAAI,MAAM,CAAE,QAAO;AAGvC,MAAK,MAAM,CAAC,GAAG,QAAQ,OAAO,QAAQ,QAAQ,IAAI,EAAE;AAClD,MAAI,CAAC,KAAK,MAAM,CAAE;AAClB,MAAI,EAAE,SAAS,WAAW,IAAI,EAAE,SAAS,SAAS,CAAE,QAAO;;AAE7D,QAAO;;AAGT,eAAsB,kBAAkB,KAA0C;AAChF,KAAI,CAAC,WAAW,IAAI,WAAW,CAC7B,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;CAGH,IAAI;AACJ,KAAI;AACF,QAAM,WAAW,IAAI,WAAW;SAC1B;AACN,SAAO;GACL,IAAI;GACJ,OAAO;GACP,QAAQ;GACR,SAAS;GACT,OAAO,EAAE;GACV;;CAGH,MAAM,aAAa,6BAA6B,IAAI;CACpD,MAAM,WAAW,WAAW,OAAO,IAAI,CAAC,GAAG,WAAW,GAAG,OAAO,KAAK,iBAAiB;AAEtF,MAAK,MAAM,MAAM,SAEf,KADY,iBAAiB,GACtB,EAAE,MAAM,CACb,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;AAIL,KAAI,uBAAuB,CACzB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,EAAE;EACV;AAGH,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,CAAC,gDAAgD,uDAAuD;EAChH"}
|
|
@@ -2,8 +2,8 @@ import { PACKAGE_VERSION, init_package_version } from "../../package-version.js"
|
|
|
2
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../../utils/logger.js";
|
|
4
4
|
import { init_paths, resolveConfigPath, resolveExtensionsDir } from "../../config/paths.js";
|
|
5
|
+
import { init_normalize_manifest, normalizeExtensionManifest } from "../../extensions/normalize-manifest.js";
|
|
5
6
|
import { init_loader, loadConfig } from "../../config/loader.js";
|
|
6
|
-
import { normalizeExtensionManifest } from "../../extensions/normalize-manifest.js";
|
|
7
7
|
import { checkEngineCompatibility } from "../../extensions/engine-check.js";
|
|
8
8
|
import { getContextWithOpts } from "../context.js";
|
|
9
9
|
import { seedMainAgentProfileMarkdown } from "../../agent/context/workspace-seed.js";
|
|
@@ -18,6 +18,7 @@ import { Command } from "commander";
|
|
|
18
18
|
//#region src/cli/commands/extension-dev.ts
|
|
19
19
|
init_loader();
|
|
20
20
|
init_paths();
|
|
21
|
+
init_normalize_manifest();
|
|
21
22
|
init_package_version();
|
|
22
23
|
init_logger();
|
|
23
24
|
const log = createLogger("ExtensionDev");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-dev.js","names":[],"sources":["../../../../src/cli/commands/extension-dev.ts"],"sourcesContent":["import {\n existsSync,\n mkdirSync,\n readFileSync,\n symlinkSync,\n unlinkSync,\n watch,\n type FSWatcher,\n} from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { Command } from 'commander';\n\nimport { loadConfig } from '../../config/loader.js';\nimport { resolveConfigPath, resolveExtensionsDir } from '../../config/paths.js';\nimport { checkEngineCompatibility } from '../../extensions/engine-check.js';\nimport type { ExtensionManifest } from '../../extensions/types/index.js';\nimport { normalizeExtensionManifest } from '../../extensions/normalize-manifest.js';\nimport { GatewayServer } from '../../gateway/index.js';\nimport { runGatewayLoop } from '../../gateway/run-loop.js';\nimport { PACKAGE_VERSION } from '../../package-version.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { colors } from '../utils/colors.js';\nimport { getContextWithOpts } from '../context.js';\nimport { initWorkspace } from '../utils/init-workspace.js';\nimport { seedMainAgentProfileMarkdown } from '../../agent/context/workspace-seed.js';\n\nconst log = createLogger('ExtensionDev');\nconst MANIFEST = 'xopc.extension.json';\n\nfunction isRecord(x: unknown): x is Record<string, unknown> {\n return typeof x === 'object' && x !== null && !Array.isArray(x);\n}\n\nasync function ensureGatewayReady(\n configPath: string,\n workspacePath: string,\n gatewayPort: number,\n): Promise<void> {\n const result = await initWorkspace({\n configPath,\n workspacePath,\n gatewayPort,\n });\n\n if (result.configCreated || result.workspaceCreated) {\n console.log('');\n console.log('👋 First-time setup before starting the gateway...');\n console.log('');\n console.log('✅ Setup complete.');\n console.log(` Config: ${configPath}`);\n console.log(` Workspace: ${workspacePath}`);\n console.log('');\n seedMainAgentProfileMarkdown(result.config);\n }\n}\n\nfunction loadAndValidateManifest(extensionDir: string): ExtensionManifest | null {\n const manifestPath = join(extensionDir, MANIFEST);\n if (!existsSync(manifestPath)) {\n console.error(colors.red('error:'), `Missing ${MANIFEST} in ${extensionDir}`);\n return null;\n }\n try {\n const raw = JSON.parse(readFileSync(manifestPath, 'utf-8') as string) as unknown;\n if (!isRecord(raw)) {\n console.error(colors.red('error:'), 'Manifest must be a JSON object');\n return null;\n }\n const manifest = normalizeExtensionManifest(raw);\n if (!manifest.id?.trim()) {\n console.error(colors.red('error:'), 'Manifest \"id\" is required');\n return null;\n }\n if (manifest.engines?.xopc) {\n const r = checkEngineCompatibility(PACKAGE_VERSION, manifest.engines.xopc);\n if (r.parseWarning) {\n console.log(\n colors.yellow('warning:'),\n r.reason ?? 'engines.xopc could not be fully parsed — continuing',\n );\n } else if (!r.compatible) {\n console.log(\n colors.yellow('warning:'),\n r.reason ?? `engines.xopc may not match xopc ${PACKAGE_VERSION} — continuing`,\n );\n }\n }\n return manifest;\n } catch (e) {\n log.error({ err: e }, 'Failed to read manifest');\n console.error(\n colors.red('error:'),\n e instanceof Error ? e.message : String(e),\n );\n return null;\n }\n}\n\nfunction setupDevSymlink(extensionDir: string, extensionsDir: string, extensionId: string): string {\n mkdirSync(extensionsDir, { recursive: true });\n const symlinkPath = join(extensionsDir, extensionId);\n if (existsSync(symlinkPath)) {\n unlinkSync(symlinkPath);\n }\n symlinkSync(extensionDir, symlinkPath, 'dir');\n return symlinkPath;\n}\n\nfunction cleanupSymlink(symlinkPath: string | null): void {\n if (!symlinkPath) return;\n try {\n if (existsSync(symlinkPath)) {\n unlinkSync(symlinkPath);\n }\n } catch (e) {\n log.warn({ err: e, symlinkPath }, 'Failed to remove dev symlink');\n }\n}\n\nfunction shouldIgnorePath(relativePath: string): boolean {\n const parts = relativePath.split(/[/\\\\]/);\n if (parts.some((p) => p === 'node_modules')) return true;\n if (parts.some((p) => p.startsWith('.'))) return true;\n return false;\n}\n\nexport function createExtensionDevCommand(): Command {\n return new Command('dev')\n .description('Symlink an extension into the workspace for live development (optional file watch + gateway)')\n .argument('[dir]', 'Extension directory (default: current working directory)', '.')\n .option('--port <number>', 'Gateway port', '18790')\n .option('--bind <mode>', 'Gateway bind mode', 'loopback')\n .option('--no-gateway', 'Do not start the gateway (symlink only)')\n .option('--no-watch', 'Do not watch files for changes')\n .action(\n async (\n dir: string,\n options: { port: string; bind: string; gateway: boolean; watch: boolean },\n ) => {\n const extensionDir = resolve(dir || '.');\n const manifest = loadAndValidateManifest(extensionDir);\n if (!manifest) {\n process.exit(1);\n }\n\n const ctx = getContextWithOpts();\n loadConfig(ctx.configPath);\n const extensionsDir = resolveExtensionsDir();\n const symlinkPath = setupDevSymlink(extensionDir, extensionsDir, manifest.id);\n\n console.log(\n colors.green('✓'),\n `Dev symlink: ${symlinkPath} → ${extensionDir}`,\n );\n console.log(\n colors.cyan('Note:'),\n 'restart the gateway or trigger config hot-reload so the extension reload picks up changes.',\n );\n\n let debounce: ReturnType<typeof setTimeout> | null = null;\n let watcher: FSWatcher | null = null;\n\n if (options.watch) {\n try {\n watcher = watch(\n extensionDir,\n { recursive: true },\n (_event, filename) => {\n const rel = filename ? String(filename) : '';\n if (rel && shouldIgnorePath(rel)) return;\n if (debounce) clearTimeout(debounce);\n debounce = setTimeout(() => {\n const label = rel || '(unknown)';\n if (/(^|[\\\\/])xopc\\.extension\\.json$/.test(rel) || rel === MANIFEST) {\n console.log(colors.cyan('[watch]'), `manifest: ${label}`);\n } else if (/\\.(html?|css|mjs|js|tsx?|jsx|json)$/i.test(label)) {\n if (/^ui[\\\\/]/.test(rel) || /[\\\\/]ui[\\\\/]/.test(label)) {\n console.log(colors.cyan('[watch]'), `ui: ${label}`);\n } else {\n console.log(colors.cyan('[watch]'), `source: ${label}`);\n }\n } else {\n console.log(colors.cyan('[watch]'), `changed: ${label}`);\n }\n }, 300);\n },\n );\n } catch (e) {\n log.warn({ err: e }, 'fs.watch failed; continuing without watch');\n }\n }\n\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n if (debounce) clearTimeout(debounce);\n if (watcher) {\n try {\n watcher.close();\n } catch (e) {\n log.warn({ err: e }, 'watcher close failed');\n }\n }\n cleanupSymlink(symlinkPath);\n };\n\n for (const sig of ['SIGINT', 'SIGTERM'] as const) {\n process.on(sig, () => {\n cleanup();\n process.exit(0);\n });\n }\n\n if (!options.gateway) {\n if (options.watch) {\n console.log(colors.cyan('Watching…'), 'Ctrl+C to stop and remove symlink');\n } else {\n console.log(\n colors.cyan('Holding process…'),\n 'Ctrl+C to stop and remove symlink (no file watch)',\n );\n }\n await new Promise(() => {\n /* until SIGINT / SIGTERM */\n });\n return;\n }\n\n const port = parseInt(options.port, 10);\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bindRaw = options.bind.trim().toLowerCase();\n if (!bindModes.has(bindRaw)) {\n console.error(colors.red('error:'), 'Invalid --bind mode');\n cleanup();\n process.exit(1);\n }\n const bind = bindRaw as import('../../config/schema.js').GatewayBindMode;\n await ensureGatewayReady(ctx.configPath, ctx.workspacePath, port);\n const cfg = loadConfig(ctx.configPath);\n const { resolveGatewayListenPlan } = await import('../../gateway/listen.js');\n const listenPlan = resolveGatewayListenPlan({ cfg, bindOverride: bind });\n\n if (Number.isNaN(port)) {\n console.error(colors.red('error:'), 'Invalid --port');\n cleanup();\n process.exit(1);\n }\n\n console.log('🚀 Starting gateway (extension dev)…');\n console.log(` Bind: ${bind} (${listenPlan.bindHost})`);\n console.log(` Port: ${port}`);\n console.log('');\n\n try {\n await runGatewayLoop({\n configPath: ctx.configPath || resolveConfigPath(),\n port,\n start: async () => {\n const server = new GatewayServer({\n bindHost: listenPlan.bindHost,\n bind: listenPlan.bindMode,\n customBindHost: listenPlan.customBindHost,\n port,\n token: cfg?.gateway?.auth?.token,\n verbose: ctx.isVerbose,\n configPath: ctx.configPath,\n enableHotReload: true,\n });\n await server.start();\n const displayHost = listenPlan.bindHost === '0.0.0.0' ? 'localhost' : listenPlan.bindHost;\n const token = cfg?.gateway?.auth?.token;\n console.log('✅ Gateway started');\n console.log(` URL: http://${displayHost}:${port}`);\n if (token) {\n console.log(\n ` Token: ${String(token).slice(0, 8)}...${String(token).slice(-8)}`,\n );\n }\n console.log('');\n return server;\n },\n });\n } finally {\n cleanup();\n }\n },\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extension-dev.js","names":[],"sources":["../../../../src/cli/commands/extension-dev.ts"],"sourcesContent":["import {\n existsSync,\n mkdirSync,\n readFileSync,\n symlinkSync,\n unlinkSync,\n watch,\n type FSWatcher,\n} from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { Command } from 'commander';\n\nimport { loadConfig } from '../../config/loader.js';\nimport { resolveConfigPath, resolveExtensionsDir } from '../../config/paths.js';\nimport { checkEngineCompatibility } from '../../extensions/engine-check.js';\nimport type { ExtensionManifest } from '../../extensions/types/index.js';\nimport { normalizeExtensionManifest } from '../../extensions/normalize-manifest.js';\nimport { GatewayServer } from '../../gateway/index.js';\nimport { runGatewayLoop } from '../../gateway/run-loop.js';\nimport { PACKAGE_VERSION } from '../../package-version.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { colors } from '../utils/colors.js';\nimport { getContextWithOpts } from '../context.js';\nimport { initWorkspace } from '../utils/init-workspace.js';\nimport { seedMainAgentProfileMarkdown } from '../../agent/context/workspace-seed.js';\n\nconst log = createLogger('ExtensionDev');\nconst MANIFEST = 'xopc.extension.json';\n\nfunction isRecord(x: unknown): x is Record<string, unknown> {\n return typeof x === 'object' && x !== null && !Array.isArray(x);\n}\n\nasync function ensureGatewayReady(\n configPath: string,\n workspacePath: string,\n gatewayPort: number,\n): Promise<void> {\n const result = await initWorkspace({\n configPath,\n workspacePath,\n gatewayPort,\n });\n\n if (result.configCreated || result.workspaceCreated) {\n console.log('');\n console.log('👋 First-time setup before starting the gateway...');\n console.log('');\n console.log('✅ Setup complete.');\n console.log(` Config: ${configPath}`);\n console.log(` Workspace: ${workspacePath}`);\n console.log('');\n seedMainAgentProfileMarkdown(result.config);\n }\n}\n\nfunction loadAndValidateManifest(extensionDir: string): ExtensionManifest | null {\n const manifestPath = join(extensionDir, MANIFEST);\n if (!existsSync(manifestPath)) {\n console.error(colors.red('error:'), `Missing ${MANIFEST} in ${extensionDir}`);\n return null;\n }\n try {\n const raw = JSON.parse(readFileSync(manifestPath, 'utf-8') as string) as unknown;\n if (!isRecord(raw)) {\n console.error(colors.red('error:'), 'Manifest must be a JSON object');\n return null;\n }\n const manifest = normalizeExtensionManifest(raw);\n if (!manifest.id?.trim()) {\n console.error(colors.red('error:'), 'Manifest \"id\" is required');\n return null;\n }\n if (manifest.engines?.xopc) {\n const r = checkEngineCompatibility(PACKAGE_VERSION, manifest.engines.xopc);\n if (r.parseWarning) {\n console.log(\n colors.yellow('warning:'),\n r.reason ?? 'engines.xopc could not be fully parsed — continuing',\n );\n } else if (!r.compatible) {\n console.log(\n colors.yellow('warning:'),\n r.reason ?? `engines.xopc may not match xopc ${PACKAGE_VERSION} — continuing`,\n );\n }\n }\n return manifest;\n } catch (e) {\n log.error({ err: e }, 'Failed to read manifest');\n console.error(\n colors.red('error:'),\n e instanceof Error ? e.message : String(e),\n );\n return null;\n }\n}\n\nfunction setupDevSymlink(extensionDir: string, extensionsDir: string, extensionId: string): string {\n mkdirSync(extensionsDir, { recursive: true });\n const symlinkPath = join(extensionsDir, extensionId);\n if (existsSync(symlinkPath)) {\n unlinkSync(symlinkPath);\n }\n symlinkSync(extensionDir, symlinkPath, 'dir');\n return symlinkPath;\n}\n\nfunction cleanupSymlink(symlinkPath: string | null): void {\n if (!symlinkPath) return;\n try {\n if (existsSync(symlinkPath)) {\n unlinkSync(symlinkPath);\n }\n } catch (e) {\n log.warn({ err: e, symlinkPath }, 'Failed to remove dev symlink');\n }\n}\n\nfunction shouldIgnorePath(relativePath: string): boolean {\n const parts = relativePath.split(/[/\\\\]/);\n if (parts.some((p) => p === 'node_modules')) return true;\n if (parts.some((p) => p.startsWith('.'))) return true;\n return false;\n}\n\nexport function createExtensionDevCommand(): Command {\n return new Command('dev')\n .description('Symlink an extension into the workspace for live development (optional file watch + gateway)')\n .argument('[dir]', 'Extension directory (default: current working directory)', '.')\n .option('--port <number>', 'Gateway port', '18790')\n .option('--bind <mode>', 'Gateway bind mode', 'loopback')\n .option('--no-gateway', 'Do not start the gateway (symlink only)')\n .option('--no-watch', 'Do not watch files for changes')\n .action(\n async (\n dir: string,\n options: { port: string; bind: string; gateway: boolean; watch: boolean },\n ) => {\n const extensionDir = resolve(dir || '.');\n const manifest = loadAndValidateManifest(extensionDir);\n if (!manifest) {\n process.exit(1);\n }\n\n const ctx = getContextWithOpts();\n loadConfig(ctx.configPath);\n const extensionsDir = resolveExtensionsDir();\n const symlinkPath = setupDevSymlink(extensionDir, extensionsDir, manifest.id);\n\n console.log(\n colors.green('✓'),\n `Dev symlink: ${symlinkPath} → ${extensionDir}`,\n );\n console.log(\n colors.cyan('Note:'),\n 'restart the gateway or trigger config hot-reload so the extension reload picks up changes.',\n );\n\n let debounce: ReturnType<typeof setTimeout> | null = null;\n let watcher: FSWatcher | null = null;\n\n if (options.watch) {\n try {\n watcher = watch(\n extensionDir,\n { recursive: true },\n (_event, filename) => {\n const rel = filename ? String(filename) : '';\n if (rel && shouldIgnorePath(rel)) return;\n if (debounce) clearTimeout(debounce);\n debounce = setTimeout(() => {\n const label = rel || '(unknown)';\n if (/(^|[\\\\/])xopc\\.extension\\.json$/.test(rel) || rel === MANIFEST) {\n console.log(colors.cyan('[watch]'), `manifest: ${label}`);\n } else if (/\\.(html?|css|mjs|js|tsx?|jsx|json)$/i.test(label)) {\n if (/^ui[\\\\/]/.test(rel) || /[\\\\/]ui[\\\\/]/.test(label)) {\n console.log(colors.cyan('[watch]'), `ui: ${label}`);\n } else {\n console.log(colors.cyan('[watch]'), `source: ${label}`);\n }\n } else {\n console.log(colors.cyan('[watch]'), `changed: ${label}`);\n }\n }, 300);\n },\n );\n } catch (e) {\n log.warn({ err: e }, 'fs.watch failed; continuing without watch');\n }\n }\n\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n if (debounce) clearTimeout(debounce);\n if (watcher) {\n try {\n watcher.close();\n } catch (e) {\n log.warn({ err: e }, 'watcher close failed');\n }\n }\n cleanupSymlink(symlinkPath);\n };\n\n for (const sig of ['SIGINT', 'SIGTERM'] as const) {\n process.on(sig, () => {\n cleanup();\n process.exit(0);\n });\n }\n\n if (!options.gateway) {\n if (options.watch) {\n console.log(colors.cyan('Watching…'), 'Ctrl+C to stop and remove symlink');\n } else {\n console.log(\n colors.cyan('Holding process…'),\n 'Ctrl+C to stop and remove symlink (no file watch)',\n );\n }\n await new Promise(() => {\n /* until SIGINT / SIGTERM */\n });\n return;\n }\n\n const port = parseInt(options.port, 10);\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bindRaw = options.bind.trim().toLowerCase();\n if (!bindModes.has(bindRaw)) {\n console.error(colors.red('error:'), 'Invalid --bind mode');\n cleanup();\n process.exit(1);\n }\n const bind = bindRaw as import('../../config/schema.js').GatewayBindMode;\n await ensureGatewayReady(ctx.configPath, ctx.workspacePath, port);\n const cfg = loadConfig(ctx.configPath);\n const { resolveGatewayListenPlan } = await import('../../gateway/listen.js');\n const listenPlan = resolveGatewayListenPlan({ cfg, bindOverride: bind });\n\n if (Number.isNaN(port)) {\n console.error(colors.red('error:'), 'Invalid --port');\n cleanup();\n process.exit(1);\n }\n\n console.log('🚀 Starting gateway (extension dev)…');\n console.log(` Bind: ${bind} (${listenPlan.bindHost})`);\n console.log(` Port: ${port}`);\n console.log('');\n\n try {\n await runGatewayLoop({\n configPath: ctx.configPath || resolveConfigPath(),\n port,\n start: async () => {\n const server = new GatewayServer({\n bindHost: listenPlan.bindHost,\n bind: listenPlan.bindMode,\n customBindHost: listenPlan.customBindHost,\n port,\n token: cfg?.gateway?.auth?.token,\n verbose: ctx.isVerbose,\n configPath: ctx.configPath,\n enableHotReload: true,\n });\n await server.start();\n const displayHost = listenPlan.bindHost === '0.0.0.0' ? 'localhost' : listenPlan.bindHost;\n const token = cfg?.gateway?.auth?.token;\n console.log('✅ Gateway started');\n console.log(` URL: http://${displayHost}:${port}`);\n if (token) {\n console.log(\n ` Token: ${String(token).slice(0, 8)}...${String(token).slice(-8)}`,\n );\n }\n console.log('');\n return server;\n },\n });\n } finally {\n cleanup();\n }\n },\n );\n}\n"],"mappings":"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"}
|