@xagent-ai/cli 1.2.2 → 1.3.0
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/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
- package/.github/workflows/ci.yml +72 -0
- package/.github/workflows/release.yml +109 -0
- package/.gitmodules +3 -3
- package/README.md +326 -280
- package/README_CN.md +325 -279
- package/dist/ai-client/factory.d.ts +52 -0
- package/dist/ai-client/factory.d.ts.map +1 -0
- package/dist/ai-client/factory.js +132 -0
- package/dist/ai-client/factory.js.map +1 -0
- package/dist/ai-client/index.d.ts +20 -0
- package/dist/ai-client/index.d.ts.map +1 -0
- package/dist/ai-client/index.js +49 -0
- package/dist/ai-client/index.js.map +1 -0
- package/dist/ai-client/providers/anthropic.d.ts +57 -0
- package/dist/ai-client/providers/anthropic.d.ts.map +1 -0
- package/dist/ai-client/providers/anthropic.js +400 -0
- package/dist/ai-client/providers/anthropic.js.map +1 -0
- package/dist/ai-client/providers/openai.d.ts +57 -0
- package/dist/ai-client/providers/openai.d.ts.map +1 -0
- package/dist/ai-client/providers/openai.js +286 -0
- package/dist/ai-client/providers/openai.js.map +1 -0
- package/dist/ai-client/providers/remote.d.ts +111 -0
- package/dist/ai-client/providers/remote.d.ts.map +1 -0
- package/dist/ai-client/providers/remote.js +351 -0
- package/dist/ai-client/providers/remote.js.map +1 -0
- package/dist/ai-client/registry.d.ts +51 -0
- package/dist/ai-client/registry.d.ts.map +1 -0
- package/dist/ai-client/registry.js +81 -0
- package/dist/ai-client/registry.js.map +1 -0
- package/dist/ai-client/types.d.ts +260 -0
- package/dist/ai-client/types.d.ts.map +1 -0
- package/dist/ai-client/types.js +73 -0
- package/dist/ai-client/types.js.map +1 -0
- package/dist/ai-client-factory.d.ts +62 -0
- package/dist/ai-client-factory.d.ts.map +1 -0
- package/dist/ai-client-factory.js +157 -0
- package/dist/ai-client-factory.js.map +1 -0
- package/dist/auth.d.ts +23 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +160 -168
- package/dist/auth.js.map +1 -1
- package/dist/cancellation.d.ts +5 -4
- package/dist/cancellation.d.ts.map +1 -1
- package/dist/cancellation.js +55 -32
- package/dist/cancellation.js.map +1 -1
- package/dist/checkpoint.d.ts +1 -1
- package/dist/checkpoint.d.ts.map +1 -1
- package/dist/checkpoint.js +2 -2
- package/dist/checkpoint.js.map +1 -1
- package/dist/cli.js +626 -13
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +10 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +62 -25
- package/dist/config.js.map +1 -1
- package/dist/context-compressor.d.ts +81 -16
- package/dist/context-compressor.d.ts.map +1 -1
- package/dist/context-compressor.js +712 -153
- package/dist/context-compressor.js.map +1 -1
- package/dist/gui-subagent/action-parser/actionParser.d.ts.map +1 -1
- package/dist/gui-subagent/action-parser/actionParser.js +4 -2
- package/dist/gui-subagent/action-parser/actionParser.js.map +1 -1
- package/dist/gui-subagent/agent/gui-agent.d.ts +29 -2
- package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -1
- package/dist/gui-subagent/agent/gui-agent.js +87 -45
- package/dist/gui-subagent/agent/gui-agent.js.map +1 -1
- package/dist/gui-subagent/index.d.ts +16 -1
- package/dist/gui-subagent/index.d.ts.map +1 -1
- package/dist/gui-subagent/index.js +4 -0
- package/dist/gui-subagent/index.js.map +1 -1
- package/dist/gui-subagent/operator/base-operator.d.ts.map +1 -1
- package/dist/gui-subagent/operator/base-operator.js +0 -1
- package/dist/gui-subagent/operator/base-operator.js.map +1 -1
- package/dist/gui-subagent/operator/computer-operator.d.ts.map +1 -1
- package/dist/gui-subagent/operator/computer-operator.js +29 -8
- package/dist/gui-subagent/operator/computer-operator.js.map +1 -1
- package/dist/gui-subagent/types/actions.d.ts +1 -1
- package/dist/gui-subagent/types/actions.d.ts.map +1 -1
- package/dist/gui-subagent/types/actions.js +0 -1
- package/dist/gui-subagent/types/actions.js.map +1 -1
- package/dist/gui-subagent/types/operator.d.ts +1 -1
- package/dist/gui-subagent/types/operator.d.ts.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/input-processor.d.ts.map +1 -1
- package/dist/input-processor.js +6 -3
- package/dist/input-processor.js.map +1 -1
- package/dist/mcp.d.ts +5 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +81 -35
- package/dist/mcp.js.map +1 -1
- package/dist/ripgrep.d.ts +29 -0
- package/dist/ripgrep.d.ts.map +1 -0
- package/dist/ripgrep.js +292 -0
- package/dist/ripgrep.js.map +1 -0
- package/dist/session.d.ts +23 -7
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +624 -243
- package/dist/session.js.map +1 -1
- package/dist/shell.d.ts +33 -0
- package/dist/shell.d.ts.map +1 -0
- package/dist/shell.js +125 -0
- package/dist/shell.js.map +1 -0
- package/dist/skill-installer.d.ts +38 -0
- package/dist/skill-installer.d.ts.map +1 -0
- package/dist/skill-installer.js +447 -0
- package/dist/skill-installer.js.map +1 -0
- package/dist/skill-invoker.d.ts +7 -1
- package/dist/skill-invoker.d.ts.map +1 -1
- package/dist/skill-invoker.js +34 -13
- package/dist/skill-invoker.js.map +1 -1
- package/dist/skill-loader.d.ts +8 -3
- package/dist/skill-loader.d.ts.map +1 -1
- package/dist/skill-loader.js +46 -44
- package/dist/skill-loader.js.map +1 -1
- package/dist/skill-manager.d.ts +85 -0
- package/dist/skill-manager.d.ts.map +1 -0
- package/dist/skill-manager.js +340 -0
- package/dist/skill-manager.js.map +1 -0
- package/dist/slash-commands.d.ts +38 -1
- package/dist/slash-commands.d.ts.map +1 -1
- package/dist/slash-commands.js +912 -296
- package/dist/slash-commands.js.map +1 -1
- package/dist/smart-approval.d.ts.map +1 -1
- package/dist/smart-approval.js +67 -55
- package/dist/smart-approval.js.map +1 -1
- package/dist/system-prompt-generator.d.ts +6 -0
- package/dist/system-prompt-generator.d.ts.map +1 -1
- package/dist/system-prompt-generator.js +84 -34
- package/dist/system-prompt-generator.js.map +1 -1
- package/dist/terminal.d.ts +28 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +82 -0
- package/dist/terminal.js.map +1 -0
- package/dist/tools.d.ts +23 -7
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +797 -437
- package/dist/tools.js.map +1 -1
- package/dist/truncate.d.ts +55 -0
- package/dist/truncate.d.ts.map +1 -0
- package/dist/truncate.js +130 -0
- package/dist/truncate.js.map +1 -0
- package/dist/types.d.ts +27 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +17 -28
- package/dist/update.js.map +1 -1
- package/dist/workflow.d.ts +5 -1
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +60 -47
- package/dist/workflow.js.map +1 -1
- package/docs/architecture/mcp-integration-guide.md +304 -194
- package/docs/architecture/overview.md +169 -169
- package/docs/architecture/tool-system-design.md +134 -134
- package/docs/cli/commands.md +349 -238
- package/docs/smart-mode.md +281 -281
- package/docs/third-party-models.md +439 -439
- package/find-skills/SKILL.md +133 -0
- package/package.json +89 -90
- package/scripts/install-ripgrep.js +241 -0
- package/src/ai-client/factory.ts +151 -0
- package/src/ai-client/index.ts +61 -0
- package/src/ai-client/providers/anthropic.ts +466 -0
- package/src/ai-client/providers/openai.ts +342 -0
- package/src/ai-client/providers/remote.ts +436 -0
- package/src/ai-client/registry.ts +97 -0
- package/src/ai-client/types.ts +345 -0
- package/src/ai-client-factory.ts +204 -0
- package/src/auth.ts +663 -614
- package/src/cancellation.ts +205 -176
- package/src/checkpoint.ts +219 -219
- package/src/cli.ts +1406 -743
- package/src/config.ts +341 -297
- package/src/context-compressor.ts +982 -290
- package/src/conversation.ts +288 -288
- package/src/gui-subagent/action-parser/actionParser.ts +318 -315
- package/src/gui-subagent/action-parser/constants.ts +14 -14
- package/src/gui-subagent/action-parser/index.ts +8 -8
- package/src/gui-subagent/action-parser/types.ts +31 -31
- package/src/gui-subagent/agent/gui-agent.ts +1151 -1089
- package/src/gui-subagent/agent/index.ts +5 -5
- package/src/gui-subagent/index.ts +177 -163
- package/src/gui-subagent/operator/base-operator.ts +244 -245
- package/src/gui-subagent/operator/computer-operator.ts +540 -520
- package/src/gui-subagent/operator/index.ts +6 -6
- package/src/gui-subagent/types/actions.ts +260 -262
- package/src/gui-subagent/types/index.ts +6 -6
- package/src/gui-subagent/types/operator.ts +106 -106
- package/src/gui-subagent/utils.ts +51 -51
- package/src/index.ts +17 -18
- package/src/input-processor.ts +6 -3
- package/src/logger.ts +438 -438
- package/src/mcp.ts +730 -682
- package/src/memory.ts +344 -344
- package/src/ripgrep.ts +368 -0
- package/src/session-manager.ts +308 -308
- package/src/session.ts +948 -386
- package/src/shell.ts +133 -0
- package/src/skill-installer.ts +518 -0
- package/src/skill-invoker.ts +960 -935
- package/src/skill-loader.ts +501 -496
- package/src/skill-manager.ts +384 -0
- package/src/slash-commands.ts +2181 -1389
- package/src/smart-approval.ts +117 -73
- package/src/system-prompt-generator.ts +89 -34
- package/src/terminal.ts +96 -0
- package/src/theme.ts +738 -738
- package/src/tools.ts +1336 -773
- package/src/truncate.ts +173 -0
- package/src/types.ts +219 -198
- package/src/update.ts +22 -32
- package/src/workflow.ts +523 -508
- package/tsconfig.json +22 -22
- package/vitest.config.ts +19 -19
- package/dist/ai-client.d.ts +0 -86
- package/dist/ai-client.d.ts.map +0 -1
- package/dist/ai-client.js +0 -1372
- package/dist/ai-client.js.map +0 -1
- package/dist/gui-subagent/operator/browser-operator.d.ts +0 -36
- package/dist/gui-subagent/operator/browser-operator.d.ts.map +0 -1
- package/dist/gui-subagent/operator/browser-operator.js +0 -306
- package/dist/gui-subagent/operator/browser-operator.js.map +0 -1
- package/dist/gui-subagent/operator/desktop-operator.d.ts +0 -55
- package/dist/gui-subagent/operator/desktop-operator.d.ts.map +0 -1
- package/dist/gui-subagent/operator/desktop-operator.js +0 -527
- package/dist/gui-subagent/operator/desktop-operator.js.map +0 -1
- package/dist/hook.d.ts +0 -73
- package/dist/hook.d.ts.map +0 -1
- package/dist/hook.js +0 -156
- package/dist/hook.js.map +0 -1
- package/dist/input-history.d.ts +0 -24
- package/dist/input-history.d.ts.map +0 -1
- package/dist/input-history.js +0 -94
- package/dist/input-history.js.map +0 -1
- package/dist/keyboard-manager.d.ts +0 -151
- package/dist/keyboard-manager.d.ts.map +0 -1
- package/dist/keyboard-manager.js +0 -396
- package/dist/keyboard-manager.js.map +0 -1
- package/dist/print-system-prompt.d.ts +0 -2
- package/dist/print-system-prompt.d.ts.map +0 -1
- package/dist/print-system-prompt.js +0 -40
- package/dist/print-system-prompt.js.map +0 -1
- package/dist/remote-ai-client.d.ts +0 -104
- package/dist/remote-ai-client.d.ts.map +0 -1
- package/dist/remote-ai-client.js +0 -552
- package/dist/remote-ai-client.js.map +0 -1
- package/dist/sdk-output-adapter.d.ts +0 -232
- package/dist/sdk-output-adapter.d.ts.map +0 -1
- package/dist/sdk-output-adapter.js +0 -636
- package/dist/sdk-output-adapter.js.map +0 -1
- package/dist/sdk-session-v2.d.ts +0 -13
- package/dist/sdk-session-v2.d.ts.map +0 -1
- package/dist/sdk-session-v2.js +0 -46
- package/dist/sdk-session-v2.js.map +0 -1
- package/dist/sdk-session.d.ts +0 -13
- package/dist/sdk-session.d.ts.map +0 -1
- package/dist/sdk-session.js +0 -48
- package/dist/sdk-session.js.map +0 -1
- package/dist/test-boundary-conditions.d.ts.map +0 -1
- package/dist/test-boundary-conditions.js.map +0 -1
- package/dist/test-cancellation-fix.d.ts.map +0 -1
- package/dist/test-cancellation-fix.js.map +0 -1
- package/dist/test-input-history.d.ts.map +0 -1
- package/dist/test-input-history.js.map +0 -1
- package/dist/test-interaction-flow.d.ts.map +0 -1
- package/dist/test-interaction-flow.js.map +0 -1
- package/dist/test-quick.d.ts.map +0 -1
- package/dist/test-quick.js.map +0 -1
- package/dist/test-user-interaction.d.ts.map +0 -1
- package/dist/test-user-interaction.js.map +0 -1
- package/dist/tools/edit-diff.d.ts +0 -32
- package/dist/tools/edit-diff.d.ts.map +0 -1
- package/dist/tools/edit-diff.js +0 -185
- package/dist/tools/edit-diff.js.map +0 -1
- package/dist/tools/edit.d.ts +0 -11
- package/dist/tools/edit.d.ts.map +0 -1
- package/dist/tools/edit.js +0 -129
- package/dist/tools/edit.js.map +0 -1
- package/dist/unified-session.d.ts +0 -42
- package/dist/unified-session.d.ts.map +0 -1
- package/dist/unified-session.js +0 -271
- package/dist/unified-session.js.map +0 -1
- package/skills/.claude-plugin/marketplace.json +0 -45
- package/skills/README.md +0 -94
- package/skills/THIRD_PARTY_NOTICES.md +0 -405
- package/skills/skills/algorithmic-art/LICENSE.txt +0 -202
- package/skills/skills/algorithmic-art/SKILL.md +0 -405
- package/skills/skills/algorithmic-art/templates/generator_template.js +0 -223
- package/skills/skills/algorithmic-art/templates/viewer.html +0 -599
- package/skills/skills/brand-guidelines/LICENSE.txt +0 -202
- package/skills/skills/brand-guidelines/SKILL.md +0 -73
- package/skills/skills/canvas-design/LICENSE.txt +0 -202
- package/skills/skills/canvas-design/SKILL.md +0 -130
- package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +0 -94
- package/skills/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Jura-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Lora-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -93
- package/skills/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/skills/skills/doc-coauthoring/SKILL.md +0 -375
- package/skills/skills/docx/LICENSE.txt +0 -30
- package/skills/skills/docx/SKILL.md +0 -197
- package/skills/skills/docx/docx-js.md +0 -350
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/skills/skills/docx/ooxml/schemas/mce/mc.xsd +0 -75
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/skills/skills/docx/ooxml/scripts/pack.py +0 -159
- package/skills/skills/docx/ooxml/scripts/unpack.py +0 -29
- package/skills/skills/docx/ooxml/scripts/validate.py +0 -69
- package/skills/skills/docx/ooxml/scripts/validation/__init__.py +0 -15
- package/skills/skills/docx/ooxml/scripts/validation/base.py +0 -951
- package/skills/skills/docx/ooxml/scripts/validation/docx.py +0 -274
- package/skills/skills/docx/ooxml/scripts/validation/pptx.py +0 -315
- package/skills/skills/docx/ooxml/scripts/validation/redlining.py +0 -279
- package/skills/skills/docx/ooxml.md +0 -610
- package/skills/skills/docx/scripts/__init__.py +0 -1
- package/skills/skills/docx/scripts/document.py +0 -1276
- package/skills/skills/docx/scripts/templates/comments.xml +0 -3
- package/skills/skills/docx/scripts/templates/commentsExtended.xml +0 -3
- package/skills/skills/docx/scripts/templates/commentsExtensible.xml +0 -3
- package/skills/skills/docx/scripts/templates/commentsIds.xml +0 -3
- package/skills/skills/docx/scripts/templates/people.xml +0 -3
- package/skills/skills/docx/scripts/utilities.py +0 -374
- package/skills/skills/frontend-design/LICENSE.txt +0 -177
- package/skills/skills/frontend-design/SKILL.md +0 -42
- package/skills/skills/internal-comms/LICENSE.txt +0 -202
- package/skills/skills/internal-comms/SKILL.md +0 -32
- package/skills/skills/internal-comms/examples/3p-updates.md +0 -47
- package/skills/skills/internal-comms/examples/company-newsletter.md +0 -65
- package/skills/skills/internal-comms/examples/faq-answers.md +0 -30
- package/skills/skills/internal-comms/examples/general-comms.md +0 -16
- package/skills/skills/mcp-builder/LICENSE.txt +0 -202
- package/skills/skills/mcp-builder/SKILL.md +0 -236
- package/skills/skills/mcp-builder/reference/evaluation.md +0 -602
- package/skills/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
- package/skills/skills/mcp-builder/reference/node_mcp_server.md +0 -970
- package/skills/skills/mcp-builder/reference/python_mcp_server.md +0 -719
- package/skills/skills/mcp-builder/scripts/connections.py +0 -151
- package/skills/skills/mcp-builder/scripts/evaluation.py +0 -373
- package/skills/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
- package/skills/skills/mcp-builder/scripts/requirements.txt +0 -2
- package/skills/skills/pdf/LICENSE.txt +0 -30
- package/skills/skills/pdf/SKILL.md +0 -294
- package/skills/skills/pdf/forms.md +0 -205
- package/skills/skills/pdf/reference.md +0 -612
- package/skills/skills/pdf/scripts/check_bounding_boxes.py +0 -70
- package/skills/skills/pdf/scripts/check_bounding_boxes_test.py +0 -226
- package/skills/skills/pdf/scripts/check_fillable_fields.py +0 -12
- package/skills/skills/pdf/scripts/convert_pdf_to_images.py +0 -35
- package/skills/skills/pdf/scripts/create_validation_image.py +0 -41
- package/skills/skills/pdf/scripts/extract_form_field_info.py +0 -152
- package/skills/skills/pdf/scripts/fill_fillable_fields.py +0 -114
- package/skills/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -108
- package/skills/skills/pptx/LICENSE.txt +0 -30
- package/skills/skills/pptx/SKILL.md +0 -484
- package/skills/skills/pptx/html2pptx.md +0 -625
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/skills/skills/pptx/ooxml/schemas/mce/mc.xsd +0 -75
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/skills/skills/pptx/ooxml/scripts/pack.py +0 -159
- package/skills/skills/pptx/ooxml/scripts/unpack.py +0 -29
- package/skills/skills/pptx/ooxml/scripts/validate.py +0 -69
- package/skills/skills/pptx/ooxml/scripts/validation/__init__.py +0 -15
- package/skills/skills/pptx/ooxml/scripts/validation/base.py +0 -951
- package/skills/skills/pptx/ooxml/scripts/validation/docx.py +0 -274
- package/skills/skills/pptx/ooxml/scripts/validation/pptx.py +0 -315
- package/skills/skills/pptx/ooxml/scripts/validation/redlining.py +0 -279
- package/skills/skills/pptx/ooxml.md +0 -427
- package/skills/skills/pptx/scripts/html2pptx.js +0 -979
- package/skills/skills/pptx/scripts/inventory.py +0 -1020
- package/skills/skills/pptx/scripts/rearrange.py +0 -231
- package/skills/skills/pptx/scripts/replace.py +0 -385
- package/skills/skills/pptx/scripts/thumbnail.py +0 -450
- package/skills/skills/skill-creator/LICENSE.txt +0 -202
- package/skills/skills/skill-creator/SKILL.md +0 -356
- package/skills/skills/skill-creator/references/output-patterns.md +0 -82
- package/skills/skills/skill-creator/references/workflows.md +0 -28
- package/skills/skills/skill-creator/scripts/init_skill.py +0 -303
- package/skills/skills/skill-creator/scripts/package_skill.py +0 -110
- package/skills/skills/skill-creator/scripts/quick_validate.py +0 -95
- package/skills/skills/slack-gif-creator/LICENSE.txt +0 -202
- package/skills/skills/slack-gif-creator/SKILL.md +0 -254
- package/skills/skills/slack-gif-creator/core/easing.py +0 -234
- package/skills/skills/slack-gif-creator/core/frame_composer.py +0 -176
- package/skills/skills/slack-gif-creator/core/gif_builder.py +0 -269
- package/skills/skills/slack-gif-creator/core/validators.py +0 -136
- package/skills/skills/slack-gif-creator/requirements.txt +0 -4
- package/skills/skills/theme-factory/LICENSE.txt +0 -202
- package/skills/skills/theme-factory/SKILL.md +0 -59
- package/skills/skills/theme-factory/theme-showcase.pdf +0 -0
- package/skills/skills/theme-factory/themes/arctic-frost.md +0 -19
- package/skills/skills/theme-factory/themes/botanical-garden.md +0 -19
- package/skills/skills/theme-factory/themes/desert-rose.md +0 -19
- package/skills/skills/theme-factory/themes/forest-canopy.md +0 -19
- package/skills/skills/theme-factory/themes/golden-hour.md +0 -19
- package/skills/skills/theme-factory/themes/midnight-galaxy.md +0 -19
- package/skills/skills/theme-factory/themes/modern-minimalist.md +0 -19
- package/skills/skills/theme-factory/themes/ocean-depths.md +0 -19
- package/skills/skills/theme-factory/themes/sunset-boulevard.md +0 -19
- package/skills/skills/theme-factory/themes/tech-innovation.md +0 -19
- package/skills/skills/web-artifacts-builder/LICENSE.txt +0 -202
- package/skills/skills/web-artifacts-builder/SKILL.md +0 -74
- package/skills/skills/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
- package/skills/skills/web-artifacts-builder/scripts/init-artifact.sh +0 -322
- package/skills/skills/webapp-testing/LICENSE.txt +0 -202
- package/skills/skills/webapp-testing/SKILL.md +0 -96
- package/skills/skills/webapp-testing/examples/console_logging.py +0 -35
- package/skills/skills/webapp-testing/examples/element_discovery.py +0 -40
- package/skills/skills/webapp-testing/examples/static_html_automation.py +0 -33
- package/skills/skills/webapp-testing/scripts/with_server.py +0 -106
- package/skills/skills/xlsx/LICENSE.txt +0 -30
- package/skills/skills/xlsx/SKILL.md +0 -289
- package/skills/skills/xlsx/recalc.py +0 -178
- package/skills/spec/agent-skills-spec.md +0 -3
- package/skills/template/SKILL.md +0 -6
- package/src/ai-client.ts +0 -1560
- package/src/remote-ai-client.ts +0 -664
package/dist/slash-commands.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { select, confirm, text } from '@clack/prompts';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import ora from 'ora';
|
|
4
4
|
import fs from 'fs/promises';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { ExecutionMode, AuthType } from './types.js';
|
|
7
|
+
import { fetchDefaultModels } from './ai-client/providers/remote.js';
|
|
7
8
|
import { getToolRegistry } from './tools.js';
|
|
8
9
|
import { getAgentManager } from './agents.js';
|
|
9
10
|
import { getMemoryManager } from './memory.js';
|
|
@@ -11,10 +12,11 @@ import { getMCPManager } from './mcp.js';
|
|
|
11
12
|
import { getCheckpointManager } from './checkpoint.js';
|
|
12
13
|
import { getConfigManager } from './config.js';
|
|
13
14
|
import { getLogger } from './logger.js';
|
|
14
|
-
import { getContextCompressor } from './context-compressor.js';
|
|
15
|
+
import { getContextCompressor, } from './context-compressor.js';
|
|
15
16
|
import { getConversationManager } from './conversation.js';
|
|
16
17
|
import { icons, colors } from './theme.js';
|
|
17
|
-
import {
|
|
18
|
+
import { ensureTtySane } from './terminal.js';
|
|
19
|
+
import { AuthService, selectAuthType, THIRD_PARTY_PROVIDERS, VLM_PROVIDERS } from './auth.js';
|
|
18
20
|
const logger = getLogger();
|
|
19
21
|
export class SlashCommandHandler {
|
|
20
22
|
configManager;
|
|
@@ -27,6 +29,8 @@ export class SlashCommandHandler {
|
|
|
27
29
|
conversationHistory = [];
|
|
28
30
|
onClearCallback = null;
|
|
29
31
|
onSystemPromptUpdate = null;
|
|
32
|
+
onConfigUpdate = null;
|
|
33
|
+
remoteAIClient = null; // Reference to InteractiveSession's remoteAIClient
|
|
30
34
|
constructor() {
|
|
31
35
|
this.configManager = getConfigManager(process.cwd());
|
|
32
36
|
this.agentManager = getAgentManager(process.cwd());
|
|
@@ -36,6 +40,12 @@ export class SlashCommandHandler {
|
|
|
36
40
|
this.contextCompressor = getContextCompressor();
|
|
37
41
|
this.conversationManager = getConversationManager();
|
|
38
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Set remote AI client reference (called from InteractiveSession)
|
|
45
|
+
*/
|
|
46
|
+
setRemoteAIClient(client) {
|
|
47
|
+
this.remoteAIClient = client;
|
|
48
|
+
}
|
|
39
49
|
/**
|
|
40
50
|
* Set callback for clearing conversation
|
|
41
51
|
*/
|
|
@@ -48,6 +58,12 @@ export class SlashCommandHandler {
|
|
|
48
58
|
setSystemPromptUpdateCallback(callback) {
|
|
49
59
|
this.onSystemPromptUpdate = callback;
|
|
50
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Set callback for config update (called after /auth changes config)
|
|
63
|
+
*/
|
|
64
|
+
setConfigUpdateCallback(callback) {
|
|
65
|
+
this.onConfigUpdate = callback;
|
|
66
|
+
}
|
|
51
67
|
/**
|
|
52
68
|
* Set current conversation history (includes all user/assistant/tool messages)
|
|
53
69
|
*/
|
|
@@ -91,8 +107,11 @@ export class SlashCommandHandler {
|
|
|
91
107
|
case 'mcp':
|
|
92
108
|
await this.handleMcp(args);
|
|
93
109
|
break;
|
|
94
|
-
case '
|
|
95
|
-
await this.
|
|
110
|
+
case 'skill':
|
|
111
|
+
await this.handleSkill(args);
|
|
112
|
+
break;
|
|
113
|
+
case 'model':
|
|
114
|
+
await this.handleModel();
|
|
96
115
|
break;
|
|
97
116
|
case 'memory':
|
|
98
117
|
await this.handleMemory(args);
|
|
@@ -118,9 +137,14 @@ export class SlashCommandHandler {
|
|
|
118
137
|
case 'compress':
|
|
119
138
|
await this.handleCompress(args);
|
|
120
139
|
break;
|
|
140
|
+
case 'update':
|
|
141
|
+
await this.handleUpdate();
|
|
142
|
+
break;
|
|
121
143
|
default:
|
|
122
144
|
logger.warn(`Unknown command: /${command}`, 'Type /help for available commands');
|
|
123
145
|
}
|
|
146
|
+
// Ensure stdin is in raw mode for proper input handling after @clack/prompts usage
|
|
147
|
+
ensureTtySane();
|
|
124
148
|
return true;
|
|
125
149
|
}
|
|
126
150
|
async showHelp() {
|
|
@@ -128,7 +152,10 @@ export class SlashCommandHandler {
|
|
|
128
152
|
console.log('');
|
|
129
153
|
console.log(colors.primaryBright('╔════════════════════════════════════════════════════════════╗'));
|
|
130
154
|
console.log(colors.primaryBright('║') + ' '.repeat(56) + colors.primaryBright('║'));
|
|
131
|
-
console.log(' '.repeat(14) +
|
|
155
|
+
console.log(' '.repeat(14) +
|
|
156
|
+
colors.gradient('📚 XAGENT CLI Help') +
|
|
157
|
+
' '.repeat(31) +
|
|
158
|
+
colors.primaryBright('║'));
|
|
132
159
|
console.log(colors.primaryBright('║') + ' '.repeat(56) + colors.primaryBright('║'));
|
|
133
160
|
console.log(colors.primaryBright('╚════════════════════════════════════════════════════════════╝'));
|
|
134
161
|
console.log('');
|
|
@@ -146,20 +173,20 @@ export class SlashCommandHandler {
|
|
|
146
173
|
cmd: '/help [command]',
|
|
147
174
|
desc: 'Show help information',
|
|
148
175
|
detail: 'View all available commands or detailed description of specific command',
|
|
149
|
-
example: '/help\n/help mode'
|
|
176
|
+
example: '/help\n/help mode',
|
|
150
177
|
},
|
|
151
178
|
{
|
|
152
179
|
cmd: '/clear',
|
|
153
180
|
desc: 'Clear conversation history',
|
|
154
181
|
detail: 'Clear all conversation records of current session, start new conversation',
|
|
155
|
-
example: '/clear'
|
|
182
|
+
example: '/clear',
|
|
156
183
|
},
|
|
157
184
|
{
|
|
158
185
|
cmd: '/exit',
|
|
159
186
|
desc: 'Exit program',
|
|
160
187
|
detail: 'Safely exit XAGENT CLI',
|
|
161
|
-
example: '/exit'
|
|
162
|
-
}
|
|
188
|
+
example: '/exit',
|
|
189
|
+
},
|
|
163
190
|
]);
|
|
164
191
|
// Project Management
|
|
165
192
|
this.showHelpCategory('Project Management', [
|
|
@@ -167,14 +194,14 @@ export class SlashCommandHandler {
|
|
|
167
194
|
cmd: '/init',
|
|
168
195
|
desc: 'Initialize project context',
|
|
169
196
|
detail: 'Create XAGENT.md file in current directory, used to store project context information',
|
|
170
|
-
example: '/init'
|
|
197
|
+
example: '/init',
|
|
171
198
|
},
|
|
172
199
|
{
|
|
173
200
|
cmd: '/memory [show|clear]',
|
|
174
201
|
desc: 'Manage project memory',
|
|
175
202
|
detail: 'View or clear memory (global, current, all, or filename)',
|
|
176
|
-
example: '/memory show\n/memory clear\n/memory clear global\n/memory clear all'
|
|
177
|
-
}
|
|
203
|
+
example: '/memory show\n/memory clear\n/memory clear global\n/memory clear all',
|
|
204
|
+
},
|
|
178
205
|
]);
|
|
179
206
|
// Authentication & Configuration
|
|
180
207
|
this.showHelpCategory('Authentication & Configuration', [
|
|
@@ -182,7 +209,7 @@ export class SlashCommandHandler {
|
|
|
182
209
|
cmd: '/auth',
|
|
183
210
|
desc: 'Configure authentication information',
|
|
184
211
|
detail: 'Change or view current authentication configuration',
|
|
185
|
-
example: '/auth'
|
|
212
|
+
example: '/auth',
|
|
186
213
|
},
|
|
187
214
|
{
|
|
188
215
|
cmd: '/mode [mode]',
|
|
@@ -194,14 +221,14 @@ export class SlashCommandHandler {
|
|
|
194
221
|
'accept_edits - Automatically accept edit operations',
|
|
195
222
|
'plan - Plan before executing',
|
|
196
223
|
'default - Safe execution, requires confirmation',
|
|
197
|
-
'smart - Smart approval (recommended)'
|
|
198
|
-
]
|
|
224
|
+
'smart - Smart approval (recommended)',
|
|
225
|
+
],
|
|
199
226
|
},
|
|
200
227
|
{
|
|
201
228
|
cmd: '/think [on|off|display]',
|
|
202
229
|
desc: 'Control thinking mode',
|
|
203
230
|
detail: 'Enable/disable AI thinking process display',
|
|
204
|
-
example: '/think on\n/think off\n/think display compact'
|
|
231
|
+
example: '/think on\n/think off\n/think display compact',
|
|
205
232
|
},
|
|
206
233
|
// {
|
|
207
234
|
// cmd: '/language [zh|en]',
|
|
@@ -213,8 +240,8 @@ export class SlashCommandHandler {
|
|
|
213
240
|
cmd: '/theme',
|
|
214
241
|
desc: 'Switch theme',
|
|
215
242
|
detail: 'Change UI theme style',
|
|
216
|
-
example: '/theme'
|
|
217
|
-
}
|
|
243
|
+
example: '/theme',
|
|
244
|
+
},
|
|
218
245
|
]);
|
|
219
246
|
// Feature Extensions
|
|
220
247
|
this.showHelpCategory('Feature Extensions', [
|
|
@@ -222,13 +249,19 @@ export class SlashCommandHandler {
|
|
|
222
249
|
cmd: '/agents [list|online|install|remove]',
|
|
223
250
|
desc: 'Manage sub-agents',
|
|
224
251
|
detail: 'View, install or remove specialized AI sub-agents',
|
|
225
|
-
example: '/agents list\n/agents online\n/agents install explore-agent'
|
|
252
|
+
example: '/agents list\n/agents online\n/agents install explore-agent',
|
|
226
253
|
},
|
|
227
254
|
{
|
|
228
255
|
cmd: '/mcp [list|add|remove|refresh]',
|
|
229
256
|
desc: 'Manage MCP servers',
|
|
230
257
|
detail: 'Manage Model Context Protocol servers',
|
|
231
|
-
example: '/mcp list\n/mcp add server-name'
|
|
258
|
+
example: '/mcp list\n/mcp add server-name',
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
cmd: '/skill [list|add|remove]',
|
|
262
|
+
desc: 'Manage skills',
|
|
263
|
+
detail: 'Install, list, or remove skills from ~/.xagent/skills',
|
|
264
|
+
example: '/skill list\n/skill add ./my-skill\n/skill add owner/repo\n/skill remove my-skill'
|
|
232
265
|
},
|
|
233
266
|
{
|
|
234
267
|
cmd: '/vlm',
|
|
@@ -236,12 +269,18 @@ export class SlashCommandHandler {
|
|
|
236
269
|
detail: 'Configure Vision-Language Model for browser/desktop automation',
|
|
237
270
|
example: '/vlm'
|
|
238
271
|
},
|
|
272
|
+
{
|
|
273
|
+
cmd: '/model',
|
|
274
|
+
desc: 'Configure LLM/VLM models',
|
|
275
|
+
detail: 'Configure or switch LLM and VLM models for remote mode',
|
|
276
|
+
example: '/model',
|
|
277
|
+
},
|
|
239
278
|
{
|
|
240
279
|
cmd: '/tools [verbose|simple]',
|
|
241
280
|
desc: 'Manage tool display',
|
|
242
281
|
detail: 'View available tools or switch tool call display mode',
|
|
243
|
-
example: '/tools\n/tools verbose\n/tools simple'
|
|
244
|
-
}
|
|
282
|
+
example: '/tools\n/tools verbose\n/tools simple',
|
|
283
|
+
},
|
|
245
284
|
]);
|
|
246
285
|
// Advanced Features
|
|
247
286
|
this.showHelpCategory('Advanced Features', [
|
|
@@ -249,26 +288,32 @@ export class SlashCommandHandler {
|
|
|
249
288
|
cmd: '/restore',
|
|
250
289
|
desc: 'Restore from checkpoint',
|
|
251
290
|
detail: 'Restore conversation state from historical checkpoints',
|
|
252
|
-
example: '/restore'
|
|
291
|
+
example: '/restore',
|
|
253
292
|
},
|
|
254
293
|
{
|
|
255
294
|
cmd: '/compress [on|off|max_message|max_token|exec]',
|
|
256
295
|
desc: 'Manage context compression',
|
|
257
296
|
detail: 'Configure compression settings or execute compression manually',
|
|
258
|
-
example: '/compress\n/compress exec\n/compress on\n/compress max_message 50\n/compress max_token 1500000'
|
|
297
|
+
example: '/compress\n/compress exec\n/compress on\n/compress max_message 50\n/compress max_token 1500000',
|
|
259
298
|
},
|
|
260
299
|
{
|
|
261
300
|
cmd: '/stats',
|
|
262
301
|
desc: 'Show session statistics',
|
|
263
302
|
detail: 'View statistics information of current session',
|
|
264
|
-
example: '/stats'
|
|
303
|
+
example: '/stats',
|
|
265
304
|
},
|
|
266
305
|
{
|
|
267
306
|
cmd: '/about',
|
|
268
307
|
desc: 'Show version information',
|
|
269
308
|
detail: 'View version and related information of XAGENT CLI',
|
|
270
|
-
example: '/about'
|
|
271
|
-
}
|
|
309
|
+
example: '/about',
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
cmd: '/update',
|
|
313
|
+
desc: 'Check for updates',
|
|
314
|
+
detail: 'Check for new versions and update xAgent CLI',
|
|
315
|
+
example: '/update',
|
|
316
|
+
},
|
|
272
317
|
]);
|
|
273
318
|
// Keyboard Shortcuts
|
|
274
319
|
console.log('');
|
|
@@ -287,18 +332,18 @@ export class SlashCommandHandler {
|
|
|
287
332
|
console.log(colors.primaryBright(title));
|
|
288
333
|
console.log(colors.border(separator));
|
|
289
334
|
console.log('');
|
|
290
|
-
commands.forEach(cmd => {
|
|
335
|
+
commands.forEach((cmd) => {
|
|
291
336
|
console.log(colors.primaryBright(` ${cmd.cmd}`));
|
|
292
337
|
console.log(colors.textDim(` ${cmd.desc}`));
|
|
293
338
|
console.log(colors.textMuted(` ${cmd.detail}`));
|
|
294
339
|
if (cmd.modes) {
|
|
295
340
|
console.log(colors.textDim(` Available modes:`));
|
|
296
|
-
cmd.modes.forEach(mode => {
|
|
341
|
+
cmd.modes.forEach((mode) => {
|
|
297
342
|
console.log(colors.textDim(` • ${mode}`));
|
|
298
343
|
});
|
|
299
344
|
}
|
|
300
345
|
console.log(colors.accent(` Examples:`));
|
|
301
|
-
cmd.example.split('\n').forEach(ex => {
|
|
346
|
+
cmd.example.split('\n').forEach((ex) => {
|
|
302
347
|
console.log(colors.codeText(` ${ex}`));
|
|
303
348
|
});
|
|
304
349
|
console.log('');
|
|
@@ -317,9 +362,9 @@ export class SlashCommandHandler {
|
|
|
317
362
|
async handleClear() {
|
|
318
363
|
// Clear local conversation history
|
|
319
364
|
this.conversationHistory = [];
|
|
320
|
-
// Clear ConversationManager
|
|
365
|
+
// Clear current conversation in ConversationManager
|
|
321
366
|
await this.conversationManager.clearCurrentConversation();
|
|
322
|
-
// Call callback to notify InteractiveSession
|
|
367
|
+
// Call callback to notify InteractiveSession to clear conversation
|
|
323
368
|
if (this.onClearCallback) {
|
|
324
369
|
this.onClearCallback();
|
|
325
370
|
}
|
|
@@ -331,37 +376,131 @@ export class SlashCommandHandler {
|
|
|
331
376
|
}
|
|
332
377
|
async handleAuth() {
|
|
333
378
|
logger.section('Authentication Management');
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
345
|
-
|
|
379
|
+
// Show current authentication configuration
|
|
380
|
+
const authConfig = this.configManager.getAuthConfig();
|
|
381
|
+
const isRemote = authConfig.type === AuthType.OAUTH_XAGENT;
|
|
382
|
+
const currentType = isRemote ? 'xAgent (Remote)' : 'Third-party API (Local)';
|
|
383
|
+
console.log(chalk.cyan('\n📋 Current Authentication Configuration:\n'));
|
|
384
|
+
console.log(` ${chalk.yellow('Mode:')} ${currentType}`);
|
|
385
|
+
if (isRemote) {
|
|
386
|
+
// Remote mode: show remote_llmModelName and remote_vlmModelName
|
|
387
|
+
const llmModel = authConfig.remote_llmModelName || 'Not set';
|
|
388
|
+
const vlmModel = authConfig.remote_vlmModelName || 'Not set';
|
|
389
|
+
console.log(` ${chalk.yellow('LLM Model:')} ${llmModel}`);
|
|
390
|
+
console.log(` ${chalk.yellow('VLM Model:')} ${vlmModel}`);
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
// Local mode: show modelName (LLM) and guiSubagentModel (VLM)
|
|
394
|
+
const llmModel = authConfig.modelName || 'Not set';
|
|
395
|
+
const vlmModel = this.configManager.get('guiSubagentModel') || 'Not set';
|
|
396
|
+
console.log(` ${chalk.yellow('LLM Model:')} ${llmModel}`);
|
|
397
|
+
console.log(` ${chalk.yellow('VLM Model:')} ${vlmModel}`);
|
|
398
|
+
}
|
|
399
|
+
console.log('');
|
|
400
|
+
const action = await select({
|
|
401
|
+
message: 'Select action:',
|
|
402
|
+
options: [
|
|
403
|
+
{ value: 'switch', label: 'Switch authentication method' },
|
|
404
|
+
{ value: 'back', label: 'Back' },
|
|
405
|
+
],
|
|
406
|
+
});
|
|
346
407
|
if (action === 'back') {
|
|
347
408
|
return;
|
|
348
409
|
}
|
|
349
|
-
if (action === '
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
410
|
+
if (action === 'switch') {
|
|
411
|
+
// Use the same selection UI as initial setup
|
|
412
|
+
const confirmSwitch = await confirm({
|
|
413
|
+
message: `Switch from "${currentType}" to another authentication method?`,
|
|
414
|
+
});
|
|
415
|
+
if (confirmSwitch === false || confirmSwitch === undefined) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
// Select authentication type (same as initial setup)
|
|
419
|
+
const authType = await selectAuthType();
|
|
420
|
+
if (authType === AuthType.OAUTH_XAGENT) {
|
|
421
|
+
// Switch to xAgent (Remote mode)
|
|
422
|
+
const authService = new AuthService({
|
|
423
|
+
type: AuthType.OAUTH_XAGENT,
|
|
424
|
+
apiKey: '',
|
|
425
|
+
baseUrl: '',
|
|
426
|
+
xagentApiBaseUrl: authConfig.xagentApiBaseUrl,
|
|
427
|
+
});
|
|
428
|
+
const success = await authService.authenticate();
|
|
429
|
+
if (success) {
|
|
430
|
+
const newAuthConfig = authService.getAuthConfig();
|
|
431
|
+
this.configManager.setAuthConfig({
|
|
432
|
+
selectedAuthType: newAuthConfig.type,
|
|
433
|
+
apiKey: newAuthConfig.apiKey,
|
|
434
|
+
refreshToken: newAuthConfig.refreshToken,
|
|
435
|
+
baseUrl: newAuthConfig.baseUrl,
|
|
436
|
+
modelName: '',
|
|
437
|
+
xagentApiBaseUrl: newAuthConfig.xagentApiBaseUrl,
|
|
438
|
+
guiSubagentModel: '',
|
|
439
|
+
guiSubagentBaseUrl: 'https://www.xagent-colife.net/v3',
|
|
440
|
+
guiSubagentApiKey: '',
|
|
441
|
+
});
|
|
442
|
+
// Set default remote model settings if not already set
|
|
443
|
+
// Fetch default models from /models/default endpoint
|
|
444
|
+
const webBaseUrl = newAuthConfig.xagentApiBaseUrl || 'https://www.xagent-colife.net';
|
|
445
|
+
let defaultLlmName = '';
|
|
446
|
+
let defaultVlmName = '';
|
|
447
|
+
try {
|
|
448
|
+
console.log(chalk.cyan('\n📊 Fetching default models from remote server...'));
|
|
449
|
+
const defaults = await fetchDefaultModels(newAuthConfig.apiKey || '', webBaseUrl);
|
|
450
|
+
if (defaults.llm?.name) {
|
|
451
|
+
defaultLlmName = defaults.llm.name;
|
|
452
|
+
console.log(chalk.cyan(` LLM Model: ${defaults.llm.name}`));
|
|
453
|
+
}
|
|
454
|
+
if (defaults.vlm?.name) {
|
|
455
|
+
defaultVlmName = defaults.vlm.name;
|
|
456
|
+
console.log(chalk.cyan(` VLM Model: ${defaults.vlm.name}`));
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
console.log(chalk.yellow(` ⚠️ Failed to fetch default models: ${error.message}`));
|
|
461
|
+
console.log(chalk.yellow(' ⚠️ Use /model command to select models manually.'));
|
|
462
|
+
}
|
|
463
|
+
console.log('');
|
|
464
|
+
this.configManager.set('remote_llmModelName', defaultLlmName);
|
|
465
|
+
this.configManager.set('remote_vlmModelName', defaultVlmName);
|
|
466
|
+
this.configManager.save('global');
|
|
467
|
+
// Notify InteractiveSession to update aiClient config
|
|
468
|
+
if (this.onConfigUpdate) {
|
|
469
|
+
this.onConfigUpdate();
|
|
470
|
+
}
|
|
471
|
+
console.log(chalk.green('\n✅ Authentication switched to xAgent (Remote mode)!'));
|
|
472
|
+
// Removed: logging partial token for security
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
// Switch to Third-party API (Local mode)
|
|
477
|
+
const authService = new AuthService({
|
|
478
|
+
type: AuthType.OPENAI_COMPATIBLE,
|
|
479
|
+
apiKey: '',
|
|
480
|
+
baseUrl: '',
|
|
481
|
+
modelName: '',
|
|
482
|
+
});
|
|
483
|
+
const success = await authService.authenticate();
|
|
484
|
+
if (success) {
|
|
485
|
+
const newAuthConfig = authService.getAuthConfig();
|
|
486
|
+
this.configManager.setAuthConfig({
|
|
487
|
+
selectedAuthType: newAuthConfig.type,
|
|
488
|
+
apiKey: newAuthConfig.apiKey,
|
|
489
|
+
baseUrl: newAuthConfig.baseUrl,
|
|
490
|
+
modelName: newAuthConfig.modelName,
|
|
491
|
+
xagentApiBaseUrl: '',
|
|
492
|
+
refreshToken: '',
|
|
493
|
+
guiSubagentModel: '',
|
|
494
|
+
guiSubagentBaseUrl: '',
|
|
495
|
+
guiSubagentApiKey: '',
|
|
496
|
+
});
|
|
497
|
+
this.configManager.save('global');
|
|
498
|
+
// Notify InteractiveSession to update aiClient config
|
|
499
|
+
if (this.onConfigUpdate) {
|
|
500
|
+
this.onConfigUpdate();
|
|
501
|
+
}
|
|
502
|
+
console.log(chalk.green('\n✅ Authentication switched to Third-party API (Local mode)!'));
|
|
361
503
|
}
|
|
362
|
-
]);
|
|
363
|
-
if (selectAuthType) {
|
|
364
|
-
logger.warn('Please restart xAgent CLI and run /auth again', 'Authentication changes require restart');
|
|
365
504
|
}
|
|
366
505
|
}
|
|
367
506
|
}
|
|
@@ -371,35 +510,33 @@ export class SlashCommandHandler {
|
|
|
371
510
|
const currentAuthType = authConfig.type;
|
|
372
511
|
if (currentAuthType !== AuthType.OAUTH_XAGENT) {
|
|
373
512
|
console.log(chalk.yellow('\n⚠️ Current authentication type is not OAuth xAgent.'));
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
message: 'Do you want to switch to OAuth xAgent authentication?',
|
|
379
|
-
default: false
|
|
380
|
-
}
|
|
381
|
-
]);
|
|
382
|
-
if (!proceed) {
|
|
513
|
+
const proceed = await confirm({
|
|
514
|
+
message: 'Do you want to switch to OAuth xAgent authentication?',
|
|
515
|
+
});
|
|
516
|
+
if (proceed === false || proceed === undefined) {
|
|
383
517
|
return;
|
|
384
518
|
}
|
|
385
519
|
// Switch to OAuth xAgent
|
|
386
|
-
|
|
520
|
+
this.configManager.setAuthConfig({
|
|
387
521
|
selectedAuthType: AuthType.OAUTH_XAGENT,
|
|
388
522
|
apiKey: '',
|
|
389
523
|
refreshToken: '',
|
|
390
|
-
baseUrl: ''
|
|
524
|
+
baseUrl: '',
|
|
391
525
|
});
|
|
392
|
-
|
|
526
|
+
this.configManager.save('global');
|
|
393
527
|
console.log(chalk.green('✅ Switched to OAuth xAgent authentication.'));
|
|
394
528
|
}
|
|
395
529
|
console.log(chalk.cyan('\n🔐 Starting OAuth xAgent login...'));
|
|
396
530
|
console.log(chalk.gray(' A browser will open for you to complete authentication.\n'));
|
|
397
531
|
try {
|
|
532
|
+
// Get xagentApiBaseUrl from config (respects XAGENT_BASE_URL env var)
|
|
533
|
+
const config = this.configManager.getAuthConfig();
|
|
398
534
|
const authService = new AuthService({
|
|
399
535
|
type: AuthType.OAUTH_XAGENT,
|
|
400
536
|
apiKey: '',
|
|
401
537
|
baseUrl: '',
|
|
402
|
-
refreshToken: ''
|
|
538
|
+
refreshToken: '',
|
|
539
|
+
xagentApiBaseUrl: config.xagentApiBaseUrl,
|
|
403
540
|
});
|
|
404
541
|
const success = await authService.authenticate();
|
|
405
542
|
if (success) {
|
|
@@ -416,75 +553,320 @@ export class SlashCommandHandler {
|
|
|
416
553
|
console.log(chalk.red(`\n❌ Login error: ${error.message || 'Unknown error'}`));
|
|
417
554
|
}
|
|
418
555
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
{
|
|
434
|
-
type: 'list',
|
|
435
|
-
name: 'action',
|
|
436
|
-
message: 'Select action:',
|
|
437
|
-
choices: [
|
|
438
|
-
{ name: 'Configure VLM', value: 'configure' },
|
|
439
|
-
{ name: 'Remove VLM configuration', value: 'remove' },
|
|
440
|
-
{ name: 'Back', value: 'back' }
|
|
441
|
-
]
|
|
442
|
-
}
|
|
443
|
-
]);
|
|
444
|
-
if (action === 'back') {
|
|
445
|
-
return;
|
|
556
|
+
/**
|
|
557
|
+
* Handle /model command - Configure LLM/VLM models
|
|
558
|
+
* Supports both remote mode (xAgent) and local mode (third-party API)
|
|
559
|
+
*/
|
|
560
|
+
async handleModel() {
|
|
561
|
+
const authConfig = this.configManager.getAuthConfig();
|
|
562
|
+
// Determine mode and show appropriate UI
|
|
563
|
+
if (authConfig.type === AuthType.OAUTH_XAGENT) {
|
|
564
|
+
// Remote mode - use backend models
|
|
565
|
+
await this.handleRemoteModel();
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
// Local mode - configure third-party API directly
|
|
569
|
+
await this.handleLocalModel();
|
|
446
570
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Handle /model command for remote mode - Configure models from backend
|
|
574
|
+
*/
|
|
575
|
+
async handleRemoteModel() {
|
|
576
|
+
const authConfig = this.configManager.getAuthConfig();
|
|
577
|
+
// Auto-fetch default models if not set
|
|
578
|
+
let currentLlm = authConfig.remote_llmModelName;
|
|
579
|
+
let currentVlm = authConfig.remote_vlmModelName;
|
|
580
|
+
if (!currentLlm || !currentVlm) {
|
|
581
|
+
console.log(chalk.cyan('\n📊 Fetching default models from remote server...'));
|
|
582
|
+
// Try to use RemoteAIClient first, otherwise fetch directly
|
|
583
|
+
let defaults = null;
|
|
584
|
+
if (this.remoteAIClient) {
|
|
585
|
+
try {
|
|
586
|
+
defaults = await this.remoteAIClient.getDefaultModels();
|
|
587
|
+
}
|
|
588
|
+
catch (error) {
|
|
589
|
+
console.log(chalk.yellow(` ⚠️ Failed to get defaults from RemoteAIClient: ${error.message}`));
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
// If RemoteAIClient failed or not available, fetch directly
|
|
593
|
+
if (!defaults) {
|
|
594
|
+
try {
|
|
595
|
+
const webBaseUrl = authConfig.xagentApiBaseUrl || 'https://www.xagent-colife.net';
|
|
596
|
+
defaults = await fetchDefaultModels(authConfig.apiKey || '', webBaseUrl);
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
console.log(chalk.yellow(` ⚠️ Failed to fetch default models: ${error.message}`));
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if (defaults) {
|
|
603
|
+
if (!currentLlm && defaults.llm?.name) {
|
|
604
|
+
currentLlm = defaults.llm.name;
|
|
605
|
+
this.configManager.set('remote_llmModelName', currentLlm);
|
|
606
|
+
console.log(chalk.cyan(` Default LLM: ${defaults.llm.displayName || currentLlm}`));
|
|
607
|
+
}
|
|
608
|
+
if (!currentVlm && defaults.vlm?.name) {
|
|
609
|
+
currentVlm = defaults.vlm.name;
|
|
610
|
+
this.configManager.set('remote_vlmModelName', currentVlm);
|
|
611
|
+
console.log(chalk.cyan(` Default VLM: ${defaults.vlm.displayName || currentVlm}`));
|
|
454
612
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
await this.configManager.save('global');
|
|
461
|
-
console.log(chalk.green('✅ VLM configuration removed successfully!'));
|
|
613
|
+
this.configManager.save('global');
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
console.log(chalk.yellow(' ⚠️ Use /auth to configure remote mode first.'));
|
|
617
|
+
return;
|
|
462
618
|
}
|
|
619
|
+
}
|
|
620
|
+
// Get RemoteAIClient instance (from InteractiveSession) for model selection
|
|
621
|
+
const remoteClient = this.remoteAIClient;
|
|
622
|
+
// Display current configuration
|
|
623
|
+
console.log(chalk.cyan('\n📊 Current Model Configuration:\n'));
|
|
624
|
+
console.log(` ${chalk.yellow('LLM Model:')} ${currentLlm || 'Not set'}`);
|
|
625
|
+
console.log(` ${chalk.yellow('VLM Model:')} ${currentVlm || 'Not set'}`);
|
|
626
|
+
console.log('');
|
|
627
|
+
// Main menu
|
|
628
|
+
const action = await select({
|
|
629
|
+
message: 'Select action:',
|
|
630
|
+
options: [
|
|
631
|
+
{ value: 'llm', label: 'Change LLM model' },
|
|
632
|
+
{ value: 'vlm', label: 'Change VLM model' },
|
|
633
|
+
{ value: 'back', label: 'Back' },
|
|
634
|
+
],
|
|
635
|
+
});
|
|
636
|
+
if (action === 'back' || typeof action === 'symbol') {
|
|
463
637
|
return;
|
|
464
638
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
639
|
+
// Restore stdin raw mode after @clack/prompts interaction
|
|
640
|
+
ensureTtySane();
|
|
641
|
+
// Get and display provider list
|
|
642
|
+
try {
|
|
643
|
+
const models = await remoteClient.getRemoteModels();
|
|
644
|
+
const modelList = action === 'llm' ? models.llm : models.vlm;
|
|
645
|
+
if (modelList.length === 0) {
|
|
646
|
+
console.log(chalk.yellow('\n⚠️ No models available.'));
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
// Build choice list
|
|
650
|
+
const choices = modelList.map((m) => ({
|
|
651
|
+
name: `${m.displayName} (${m.name})`,
|
|
652
|
+
value: m.name
|
|
653
|
+
}));
|
|
654
|
+
const selectedModel = await select({
|
|
655
|
+
message: action === 'llm' ? 'Select LLM Model:' : 'Select VLM Model:',
|
|
656
|
+
options: choices
|
|
472
657
|
});
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
console.log(chalk.cyan(
|
|
658
|
+
if (typeof selectedModel !== 'string') {
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
const configKey = action === 'llm' ? 'remote_llmModelName' : 'remote_vlmModelName';
|
|
662
|
+
this.configManager.set(configKey, selectedModel);
|
|
663
|
+
this.configManager.save('global');
|
|
664
|
+
// Clear conversation history to avoid tool call ID conflicts between providers
|
|
665
|
+
if (this.onClearCallback) {
|
|
666
|
+
this.onClearCallback();
|
|
667
|
+
console.log(chalk.cyan(' Conversation cleared to avoid tool call ID conflicts between models.'));
|
|
668
|
+
}
|
|
669
|
+
// Notify InteractiveSession to update aiClient config
|
|
670
|
+
if (this.onConfigUpdate) {
|
|
671
|
+
this.onConfigUpdate();
|
|
672
|
+
}
|
|
673
|
+
console.log(chalk.green('\n✅ Model updated successfully!'));
|
|
674
|
+
console.log(` ${action === 'llm' ? 'LLM' : 'VLM'}: ${selectedModel}`);
|
|
675
|
+
}
|
|
676
|
+
catch (error) {
|
|
677
|
+
console.log(chalk.red(`\n❌ Failed to get models: ${error.message}`));
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Handle /model command for local mode - Configure third-party API directly
|
|
682
|
+
* Reuses code from initial setup flow (authenticateWithOpenAICompatible and configureAndValidateVLM)
|
|
683
|
+
*/
|
|
684
|
+
async handleLocalModel() {
|
|
685
|
+
// Display current configuration
|
|
686
|
+
const currentLlmModel = this.configManager.get('modelName') || this.configManager.getAuthConfig().modelName;
|
|
687
|
+
const currentVlmModel = this.configManager.get('guiSubagentModel');
|
|
688
|
+
console.log(chalk.cyan('\n📊 Current Local Model Configuration:\n'));
|
|
689
|
+
console.log(` ${chalk.yellow('LLM Model:')} ${currentLlmModel || 'Not set'}`);
|
|
690
|
+
console.log(` ${chalk.yellow('VLM Model:')} ${currentVlmModel || 'Not set'}`);
|
|
691
|
+
console.log('');
|
|
692
|
+
// Main menu - choose to configure LLM or VLM
|
|
693
|
+
const action = await select({
|
|
694
|
+
message: 'Select action:',
|
|
695
|
+
options: [
|
|
696
|
+
{ value: 'llm', label: 'Change LLM (select provider and API)' },
|
|
697
|
+
{ value: 'vlm', label: 'Change VLM (for GUI automation)' },
|
|
698
|
+
{ value: 'back', label: 'Back' },
|
|
699
|
+
],
|
|
700
|
+
});
|
|
701
|
+
if (action === 'back' || typeof action === 'symbol') {
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
if (action === 'llm') {
|
|
705
|
+
await this.configureLocalLLM();
|
|
706
|
+
}
|
|
707
|
+
else if (action === 'vlm') {
|
|
708
|
+
await this.configureLocalVLM();
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Configure LLM for local mode - Reuses authenticateWithOpenAICompatible logic
|
|
713
|
+
*/
|
|
714
|
+
async configureLocalLLM() {
|
|
715
|
+
// THIRD_PARTY_PROVIDERS already imported at top level
|
|
716
|
+
const provider = await select({
|
|
717
|
+
message: 'Select third-party model provider:',
|
|
718
|
+
options: THIRD_PARTY_PROVIDERS.map((p) => ({
|
|
719
|
+
value: p,
|
|
720
|
+
label: `${p.name} - ${p.description}`,
|
|
721
|
+
})),
|
|
722
|
+
});
|
|
723
|
+
if (typeof provider === 'symbol') {
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
const selectedProvider = provider;
|
|
727
|
+
let baseUrl = selectedProvider.baseUrl;
|
|
728
|
+
let modelName = selectedProvider.defaultModel;
|
|
729
|
+
if (selectedProvider.name === 'Custom') {
|
|
730
|
+
baseUrl = (await import('@clack/prompts').then(m => m.text({
|
|
731
|
+
message: 'Enter API Base URL:',
|
|
732
|
+
defaultValue: 'https://api.openai.com/v1',
|
|
733
|
+
validate: (value) => {
|
|
734
|
+
if (!value || value.trim().length === 0) {
|
|
735
|
+
return 'Base URL cannot be empty';
|
|
736
|
+
}
|
|
737
|
+
return undefined;
|
|
738
|
+
},
|
|
739
|
+
})));
|
|
740
|
+
modelName = (await import('@clack/prompts').then(m => m.text({
|
|
741
|
+
message: 'Enter model name:',
|
|
742
|
+
defaultValue: 'gpt-4',
|
|
743
|
+
validate: (value) => {
|
|
744
|
+
if (!value || value.trim().length === 0) {
|
|
745
|
+
return 'Model name cannot be empty';
|
|
746
|
+
}
|
|
747
|
+
return undefined;
|
|
748
|
+
},
|
|
749
|
+
})));
|
|
750
|
+
baseUrl = baseUrl.trim();
|
|
751
|
+
modelName = modelName.trim();
|
|
752
|
+
}
|
|
753
|
+
else {
|
|
754
|
+
console.log(chalk.cyan(`\nSelected: ${selectedProvider.name}`));
|
|
755
|
+
console.log(chalk.cyan(`API URL: ${baseUrl}`));
|
|
756
|
+
if (selectedProvider.models && selectedProvider.models.length > 0) {
|
|
757
|
+
console.log(chalk.cyan(`Available models: ${selectedProvider.models.join(', ')}`));
|
|
758
|
+
const selectedModel = await select({
|
|
759
|
+
message: 'Select model:',
|
|
760
|
+
options: selectedProvider.models.map((model) => ({
|
|
761
|
+
value: model,
|
|
762
|
+
label: model === selectedProvider.defaultModel ? `${model} (default)` : model,
|
|
763
|
+
})),
|
|
764
|
+
});
|
|
765
|
+
if (typeof selectedModel === 'symbol') {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
modelName = selectedModel;
|
|
483
769
|
}
|
|
484
770
|
else {
|
|
485
|
-
console.log(chalk.
|
|
771
|
+
console.log(chalk.cyan(`Default model: ${modelName}`));
|
|
772
|
+
const confirmModel = (await import('@clack/prompts').then(m => m.text({
|
|
773
|
+
message: `Enter model name (press Enter to use default value ${modelName}):`,
|
|
774
|
+
defaultValue: modelName,
|
|
775
|
+
validate: (value) => {
|
|
776
|
+
if (!value || value.trim().length === 0) {
|
|
777
|
+
return 'Model name cannot be empty';
|
|
778
|
+
}
|
|
779
|
+
return undefined;
|
|
780
|
+
},
|
|
781
|
+
})));
|
|
782
|
+
modelName = confirmModel.trim();
|
|
486
783
|
}
|
|
487
784
|
}
|
|
785
|
+
const apiKey = (await import('@clack/prompts').then(m => m.password({
|
|
786
|
+
message: `Enter ${selectedProvider.name} API Key:`,
|
|
787
|
+
validate: (value) => {
|
|
788
|
+
if (!value || value.trim().length === 0) {
|
|
789
|
+
return 'API Key cannot be empty';
|
|
790
|
+
}
|
|
791
|
+
return undefined;
|
|
792
|
+
},
|
|
793
|
+
})));
|
|
794
|
+
// Update config
|
|
795
|
+
this.configManager.set('baseUrl', baseUrl);
|
|
796
|
+
this.configManager.set('apiKey', apiKey.trim());
|
|
797
|
+
this.configManager.set('modelName', modelName);
|
|
798
|
+
this.configManager.save('global');
|
|
799
|
+
console.log(chalk.green('\n✅ LLM configuration updated successfully!'));
|
|
800
|
+
console.log(chalk.cyan(` Provider: ${selectedProvider.name}`));
|
|
801
|
+
console.log(chalk.cyan(` Model: ${modelName}`));
|
|
802
|
+
console.log(chalk.cyan(` API URL: ${baseUrl}`));
|
|
803
|
+
// Clear conversation and notify config update
|
|
804
|
+
if (this.onClearCallback) {
|
|
805
|
+
this.onClearCallback();
|
|
806
|
+
}
|
|
807
|
+
if (this.onConfigUpdate) {
|
|
808
|
+
this.onConfigUpdate();
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Configure VLM for local mode - Select provider and modelName (baseUrl from VLM_PROVIDERS)
|
|
813
|
+
*/
|
|
814
|
+
async configureLocalVLM() {
|
|
815
|
+
// Get current VLM config
|
|
816
|
+
const currentModel = this.configManager.get('guiSubagentModel');
|
|
817
|
+
const currentBaseUrl = this.configManager.get('guiSubagentBaseUrl');
|
|
818
|
+
console.log(chalk.cyan('\n📊 Current VLM Configuration:\n'));
|
|
819
|
+
console.log(` ${chalk.yellow('Model:')} ${currentModel || 'Not set'}`);
|
|
820
|
+
console.log(` ${chalk.yellow('Base URL:')} ${currentBaseUrl || 'Not set'}`);
|
|
821
|
+
console.log('');
|
|
822
|
+
// Step 1: Select VLM provider
|
|
823
|
+
const provider = await select({
|
|
824
|
+
message: 'Select VLM provider:',
|
|
825
|
+
options: VLM_PROVIDERS.map((p) => ({
|
|
826
|
+
value: p,
|
|
827
|
+
label: `${p.name} - ${p.defaultModel}`,
|
|
828
|
+
})),
|
|
829
|
+
});
|
|
830
|
+
// User cancelled
|
|
831
|
+
if (typeof provider === 'symbol') {
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
const selectedProvider = provider;
|
|
835
|
+
// Step 2: Select model from provider's models list
|
|
836
|
+
const model = await select({
|
|
837
|
+
message: 'Select VLM Model:',
|
|
838
|
+
options: selectedProvider.models.map((m) => ({
|
|
839
|
+
value: m,
|
|
840
|
+
label: m,
|
|
841
|
+
})),
|
|
842
|
+
});
|
|
843
|
+
// User cancelled
|
|
844
|
+
if (typeof model === 'symbol') {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
// Step 3: Get API Key
|
|
848
|
+
const apiKey = (await text({
|
|
849
|
+
message: `Enter ${selectedProvider.name} API Key:`,
|
|
850
|
+
validate: (value) => {
|
|
851
|
+
if (!value || value.trim().length === 0) {
|
|
852
|
+
return 'API Key cannot be empty';
|
|
853
|
+
}
|
|
854
|
+
return undefined;
|
|
855
|
+
},
|
|
856
|
+
}));
|
|
857
|
+
// Save configuration
|
|
858
|
+
this.configManager.set('guiSubagentModel', model);
|
|
859
|
+
this.configManager.set('guiSubagentBaseUrl', selectedProvider.baseUrl);
|
|
860
|
+
this.configManager.set('guiSubagentApiKey', apiKey);
|
|
861
|
+
this.configManager.save('global');
|
|
862
|
+
console.log(chalk.green('\n✅ VLM configuration updated successfully!'));
|
|
863
|
+
console.log(chalk.cyan(` Provider: ${selectedProvider.name}`));
|
|
864
|
+
console.log(chalk.cyan(` Model: ${model}`));
|
|
865
|
+
console.log(chalk.cyan(` Base URL: ${selectedProvider.baseUrl}`));
|
|
866
|
+
// Notify config update
|
|
867
|
+
if (this.onConfigUpdate) {
|
|
868
|
+
this.onConfigUpdate();
|
|
869
|
+
}
|
|
488
870
|
}
|
|
489
871
|
async handleMode(args) {
|
|
490
872
|
const modes = Object.values(ExecutionMode);
|
|
@@ -493,7 +875,7 @@ export class SlashCommandHandler {
|
|
|
493
875
|
const newMode = args[0].toLowerCase();
|
|
494
876
|
if (modes.includes(newMode)) {
|
|
495
877
|
this.configManager.setApprovalMode(newMode);
|
|
496
|
-
|
|
878
|
+
this.configManager.save('global');
|
|
497
879
|
console.log(chalk.green(`✅ Approval mode changed to: ${newMode}`));
|
|
498
880
|
}
|
|
499
881
|
else {
|
|
@@ -509,7 +891,7 @@ export class SlashCommandHandler {
|
|
|
509
891
|
{ mode: 'accept_edits', desc: 'Accept all edits automatically' },
|
|
510
892
|
{ mode: 'plan', desc: 'Plan before executing' },
|
|
511
893
|
{ mode: 'default', desc: 'Safe execution with confirmations' },
|
|
512
|
-
{ mode: 'smart', desc: 'Smart approval with intelligent security checks' }
|
|
894
|
+
{ mode: 'smart', desc: 'Smart approval with intelligent security checks' },
|
|
513
895
|
];
|
|
514
896
|
descriptions.forEach(({ mode, desc }) => {
|
|
515
897
|
const current = mode === currentMode ? chalk.green(' [current]') : '';
|
|
@@ -526,13 +908,13 @@ export class SlashCommandHandler {
|
|
|
526
908
|
if (action === 'on' || action === 'true' || action === '1') {
|
|
527
909
|
thinkingConfig.enabled = true;
|
|
528
910
|
this.configManager.setThinkingConfig(thinkingConfig);
|
|
529
|
-
|
|
911
|
+
this.configManager.save('global');
|
|
530
912
|
console.log(chalk.green('✅ Thinking mode enabled'));
|
|
531
913
|
}
|
|
532
914
|
else if (action === 'off' || action === 'false' || action === '0') {
|
|
533
915
|
thinkingConfig.enabled = false;
|
|
534
916
|
this.configManager.setThinkingConfig(thinkingConfig);
|
|
535
|
-
|
|
917
|
+
this.configManager.save('global');
|
|
536
918
|
console.log(chalk.green('✅ Thinking mode disabled'));
|
|
537
919
|
}
|
|
538
920
|
else if (action === 'display' && args[1]) {
|
|
@@ -540,9 +922,9 @@ export class SlashCommandHandler {
|
|
|
540
922
|
const validModes = ['full', 'compact', 'indicator'];
|
|
541
923
|
if (validModes.includes(displayMode)) {
|
|
542
924
|
thinkingConfig.displayMode = displayMode;
|
|
543
|
-
thinkingConfig.enabled = true;
|
|
925
|
+
thinkingConfig.enabled = true;
|
|
544
926
|
this.configManager.setThinkingConfig(thinkingConfig);
|
|
545
|
-
|
|
927
|
+
this.configManager.save('global');
|
|
546
928
|
console.log(chalk.green(`✅ Thinking display mode set to: ${displayMode}`));
|
|
547
929
|
}
|
|
548
930
|
else {
|
|
@@ -650,7 +1032,9 @@ export class SlashCommandHandler {
|
|
|
650
1032
|
const status = isConnected ? chalk.green('✓ Connected') : chalk.red('✗ Disconnected');
|
|
651
1033
|
const tools = server?.getToolNames() || [];
|
|
652
1034
|
const transport = serverConfig?.transport || serverConfig?.type || 'unknown';
|
|
653
|
-
const command = serverConfig?.command
|
|
1035
|
+
const command = serverConfig?.command
|
|
1036
|
+
? `${serverConfig.command} ${(serverConfig.args || []).join(' ')}`
|
|
1037
|
+
: serverConfig?.url || 'N/A';
|
|
654
1038
|
console.log('');
|
|
655
1039
|
console.log(` ${chalk.cyan(serverName)} ${status}`);
|
|
656
1040
|
console.log(` Transport: ${transport}`);
|
|
@@ -661,80 +1045,87 @@ export class SlashCommandHandler {
|
|
|
661
1045
|
logger.info(`Total: ${serverConfigs.length} server(s)`);
|
|
662
1046
|
}
|
|
663
1047
|
async addMcpServerInteractive(serverName) {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
validate: (input) => {
|
|
671
|
-
if (!input.trim()) {
|
|
672
|
-
return 'Server name is required';
|
|
673
|
-
}
|
|
674
|
-
const servers = this.mcpManager.getAllServers();
|
|
675
|
-
if (servers.some((s) => s.config?.name === input)) {
|
|
676
|
-
return 'Server with this name already exists';
|
|
677
|
-
}
|
|
678
|
-
return true;
|
|
1048
|
+
let name = (await text({
|
|
1049
|
+
message: 'Enter MCP server name:',
|
|
1050
|
+
defaultValue: serverName,
|
|
1051
|
+
validate: (value) => {
|
|
1052
|
+
if (!value || !value.trim()) {
|
|
1053
|
+
return 'Server name is required';
|
|
679
1054
|
}
|
|
1055
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(value)) {
|
|
1056
|
+
return 'Server name must contain only alphanumeric characters, hyphens, and underscores';
|
|
1057
|
+
}
|
|
1058
|
+
const servers = this.mcpManager.getAllServers();
|
|
1059
|
+
if (servers.some((s) => s.config?.name === value)) {
|
|
1060
|
+
return 'Server with this name already exists';
|
|
1061
|
+
}
|
|
1062
|
+
return undefined;
|
|
680
1063
|
},
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
1064
|
+
}));
|
|
1065
|
+
const transport = await select({
|
|
1066
|
+
message: 'Select transport type:',
|
|
1067
|
+
options: [
|
|
1068
|
+
{ value: 'stdio', label: 'Stdio (stdin/stdout)' },
|
|
1069
|
+
{ value: 'sse', label: 'HTTP/SSE' },
|
|
1070
|
+
{ value: 'http', label: 'HTTP (POST)' },
|
|
1071
|
+
],
|
|
1072
|
+
});
|
|
1073
|
+
if (typeof transport === 'symbol') {
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
let command = '';
|
|
1077
|
+
let serverArgs = [];
|
|
1078
|
+
let url = '';
|
|
1079
|
+
let authToken = '';
|
|
1080
|
+
let headers;
|
|
1081
|
+
if (transport === 'stdio') {
|
|
1082
|
+
command = (await text({
|
|
695
1083
|
message: 'Enter command (for stdio transport):',
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
{
|
|
700
|
-
type: 'input',
|
|
701
|
-
name: 'args',
|
|
1084
|
+
validate: (value) => value && value.trim() ? undefined : 'Command is required',
|
|
1085
|
+
}));
|
|
1086
|
+
const argsInput = (await text({
|
|
702
1087
|
message: 'Enter arguments (comma-separated, for stdio transport):',
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
1088
|
+
defaultValue: '',
|
|
1089
|
+
}));
|
|
1090
|
+
if (argsInput.trim()) {
|
|
1091
|
+
serverArgs = argsInput.split(',').map((a) => a.trim());
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
else {
|
|
1095
|
+
url = (await text({
|
|
709
1096
|
message: 'Enter server URL (for HTTP/SSE/HTTP transport):',
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
type: 'password',
|
|
715
|
-
name: 'authToken',
|
|
716
|
-
message: 'Enter authentication token (optional):',
|
|
717
|
-
when: (answers) => answers.transport === 'sse' || answers.transport === 'http'
|
|
718
|
-
},
|
|
719
|
-
{
|
|
720
|
-
type: 'input',
|
|
721
|
-
name: 'headers',
|
|
722
|
-
message: 'Enter custom headers as JSON (optional, e.g., {"Authorization": "Bearer token"}):',
|
|
723
|
-
when: (answers) => answers.transport === 'sse' || answers.transport === 'http',
|
|
724
|
-
filter: (input) => {
|
|
725
|
-
if (!input.trim())
|
|
726
|
-
return undefined;
|
|
1097
|
+
validate: (value) => {
|
|
1098
|
+
if (!value || !value.trim()) {
|
|
1099
|
+
return 'URL is required';
|
|
1100
|
+
}
|
|
727
1101
|
try {
|
|
728
|
-
|
|
1102
|
+
new URL(value);
|
|
1103
|
+
return undefined;
|
|
729
1104
|
}
|
|
730
1105
|
catch {
|
|
731
|
-
return
|
|
1106
|
+
return 'Invalid URL format (e.g., https://example.com)';
|
|
732
1107
|
}
|
|
1108
|
+
},
|
|
1109
|
+
}));
|
|
1110
|
+
authToken = (await text({
|
|
1111
|
+
message: 'Enter authentication token (optional):',
|
|
1112
|
+
defaultValue: '',
|
|
1113
|
+
}));
|
|
1114
|
+
const headersInput = (await text({
|
|
1115
|
+
message: 'Enter custom headers as JSON (optional, e.g., {"Authorization": "Bearer token"}):',
|
|
1116
|
+
defaultValue: '',
|
|
1117
|
+
}));
|
|
1118
|
+
if (headersInput.trim()) {
|
|
1119
|
+
try {
|
|
1120
|
+
headers = JSON.parse(headersInput);
|
|
1121
|
+
}
|
|
1122
|
+
catch {
|
|
1123
|
+
headers = undefined;
|
|
733
1124
|
}
|
|
734
1125
|
}
|
|
735
|
-
|
|
1126
|
+
}
|
|
736
1127
|
const config = {
|
|
737
|
-
transport: transport
|
|
1128
|
+
transport: transport,
|
|
738
1129
|
};
|
|
739
1130
|
if (transport === 'stdio') {
|
|
740
1131
|
config.command = command;
|
|
@@ -744,30 +1135,39 @@ export class SlashCommandHandler {
|
|
|
744
1135
|
}
|
|
745
1136
|
else {
|
|
746
1137
|
config.url = url;
|
|
747
|
-
|
|
748
|
-
|
|
1138
|
+
// Handle user input that mistakenly puts Bearer token in headers field
|
|
1139
|
+
// Detect pattern: headers looks like "Bearer xxx.yyy.zzz" (JWT token)
|
|
1140
|
+
let resolvedAuthToken = authToken;
|
|
1141
|
+
let resolvedHeaders = headers;
|
|
1142
|
+
if (headers && typeof headers === 'string' && !authToken) {
|
|
1143
|
+
const trimmedHeaders = headers.trim();
|
|
1144
|
+
if (trimmedHeaders.startsWith('Bearer ') && trimmedHeaders.split('.').length === 3) {
|
|
1145
|
+
// User mistakenly put token in headers field - extract it
|
|
1146
|
+
resolvedAuthToken = trimmedHeaders;
|
|
1147
|
+
resolvedHeaders = undefined;
|
|
1148
|
+
console.log('[MCP] Note: Detected Bearer token in headers field, moved to authToken');
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
if (resolvedAuthToken) {
|
|
1152
|
+
config.authToken = resolvedAuthToken;
|
|
749
1153
|
}
|
|
750
|
-
if (
|
|
751
|
-
config.headers =
|
|
1154
|
+
if (resolvedHeaders) {
|
|
1155
|
+
config.headers = resolvedHeaders;
|
|
752
1156
|
}
|
|
753
1157
|
}
|
|
754
1158
|
try {
|
|
755
|
-
// Save to config file
|
|
756
1159
|
this.configManager.addMcpServer(name, config);
|
|
757
|
-
|
|
758
|
-
// Register to MCP Manager
|
|
1160
|
+
this.configManager.save('global');
|
|
759
1161
|
this.mcpManager.registerServer(name, config);
|
|
760
|
-
// Connect to server (with error handling)
|
|
761
1162
|
let connected = false;
|
|
762
1163
|
try {
|
|
763
1164
|
await this.mcpManager.connectServer(name);
|
|
764
1165
|
connected = true;
|
|
765
1166
|
}
|
|
766
1167
|
catch (error) {
|
|
767
|
-
// Connection failed - cleanup
|
|
768
1168
|
this.mcpManager.disconnectServer(name);
|
|
769
1169
|
this.configManager.removeMcpServer(name);
|
|
770
|
-
|
|
1170
|
+
this.configManager.save('global');
|
|
771
1171
|
throw new Error(`Connection failed: ${error.message}`);
|
|
772
1172
|
}
|
|
773
1173
|
// Register MCP tools with simple names
|
|
@@ -790,22 +1190,21 @@ export class SlashCommandHandler {
|
|
|
790
1190
|
logger.warn('No MCP servers configured', 'Use /mcp add to add servers');
|
|
791
1191
|
return;
|
|
792
1192
|
}
|
|
793
|
-
const
|
|
1193
|
+
const serverOptions = servers.map((s) => {
|
|
794
1194
|
const tools = s.getToolNames();
|
|
795
1195
|
const status = s.isServerConnected() ? '✓' : '✗';
|
|
796
1196
|
return {
|
|
797
|
-
|
|
798
|
-
|
|
1197
|
+
value: s.config?.name,
|
|
1198
|
+
label: `${status} ${s.config?.name || 'unknown'} (${tools.length} tools)`,
|
|
799
1199
|
};
|
|
800
1200
|
});
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
]);
|
|
1201
|
+
const serverName = (await select({
|
|
1202
|
+
message: 'Select MCP server to remove:',
|
|
1203
|
+
options: serverOptions,
|
|
1204
|
+
}));
|
|
1205
|
+
if (typeof serverName === 'symbol') {
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
809
1208
|
await this.removeMcpServer(serverName);
|
|
810
1209
|
}
|
|
811
1210
|
async removeMcpServer(serverName) {
|
|
@@ -821,7 +1220,7 @@ export class SlashCommandHandler {
|
|
|
821
1220
|
toolRegistry.unregisterMCPTools(serverName);
|
|
822
1221
|
// Remove from config
|
|
823
1222
|
this.configManager.removeMcpServer(serverName);
|
|
824
|
-
|
|
1223
|
+
this.configManager.save('global');
|
|
825
1224
|
// Update system prompt to reflect removed MCP tools
|
|
826
1225
|
if (this.onSystemPromptUpdate) {
|
|
827
1226
|
await this.onSystemPromptUpdate();
|
|
@@ -914,8 +1313,7 @@ export class SlashCommandHandler {
|
|
|
914
1313
|
return;
|
|
915
1314
|
}
|
|
916
1315
|
// Clear specific file by filename or path
|
|
917
|
-
const targetMemory = memoryFiles.find((m) => path.basename(m.path) === target ||
|
|
918
|
-
m.path === target);
|
|
1316
|
+
const targetMemory = memoryFiles.find((m) => path.basename(m.path) === target || m.path === target);
|
|
919
1317
|
if (targetMemory) {
|
|
920
1318
|
try {
|
|
921
1319
|
await fs.unlink(targetMemory.path);
|
|
@@ -949,22 +1347,20 @@ export class SlashCommandHandler {
|
|
|
949
1347
|
logger.info(`Directory: ${memoriesDir}`);
|
|
950
1348
|
console.log('');
|
|
951
1349
|
memoryFiles.forEach((file) => {
|
|
952
|
-
const level = file.level === 'global'
|
|
953
|
-
|
|
954
|
-
|
|
1350
|
+
const level = file.level === 'global'
|
|
1351
|
+
? chalk.blue('[global]')
|
|
1352
|
+
: file.level === 'project'
|
|
1353
|
+
? chalk.green('[project]')
|
|
1354
|
+
: chalk.yellow('[subdirectory]');
|
|
955
1355
|
logger.info(` ${level} ${path.basename(file.path)}`);
|
|
956
1356
|
});
|
|
957
1357
|
console.log('');
|
|
958
1358
|
// logger.info('Usage: /memory clear [global|current|all|<filename>]');
|
|
959
1359
|
}
|
|
960
1360
|
async addMemory() {
|
|
961
|
-
const
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
name: 'entry',
|
|
965
|
-
message: 'Enter memory entry (opens editor):'
|
|
966
|
-
}
|
|
967
|
-
]);
|
|
1361
|
+
const entry = (await text({
|
|
1362
|
+
message: 'Enter memory entry (opens editor):',
|
|
1363
|
+
}));
|
|
968
1364
|
if (entry && entry.trim()) {
|
|
969
1365
|
await this.memoryManager.addMemoryEntry(entry.trim());
|
|
970
1366
|
console.log(chalk.green('✅ Memory entry added'));
|
|
@@ -1001,18 +1397,17 @@ export class SlashCommandHandler {
|
|
|
1001
1397
|
}
|
|
1002
1398
|
}
|
|
1003
1399
|
else {
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
1400
|
+
const checkpointOptions = checkpoints.map((cp) => ({
|
|
1401
|
+
value: cp.id,
|
|
1402
|
+
label: `${new Date(cp.timestamp).toLocaleString()} - ${cp.description}`,
|
|
1007
1403
|
}));
|
|
1008
|
-
const
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
]);
|
|
1404
|
+
const checkpointId = await select({
|
|
1405
|
+
message: 'Select checkpoint to restore:',
|
|
1406
|
+
options: checkpointOptions,
|
|
1407
|
+
});
|
|
1408
|
+
if (typeof checkpointId === 'symbol') {
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1016
1411
|
try {
|
|
1017
1412
|
await this.checkpointManager.restoreCheckpoint(checkpointId);
|
|
1018
1413
|
logger.success(`Checkpoint ${checkpointId} restored successfully!`);
|
|
@@ -1026,7 +1421,7 @@ export class SlashCommandHandler {
|
|
|
1026
1421
|
const toolRegistry = getToolRegistry();
|
|
1027
1422
|
const tools = toolRegistry.getAll();
|
|
1028
1423
|
logger.section('Available Tools');
|
|
1029
|
-
tools.forEach(tool => {
|
|
1424
|
+
tools.forEach((tool) => {
|
|
1030
1425
|
logger.info(` ${tool.name}`);
|
|
1031
1426
|
logger.info(` ${tool.description}`);
|
|
1032
1427
|
});
|
|
@@ -1045,12 +1440,12 @@ export class SlashCommandHandler {
|
|
|
1045
1440
|
const mode = args[0].toLowerCase();
|
|
1046
1441
|
if (mode === 'verbose' || mode === 'detail' || mode === 'true' || mode === 'on') {
|
|
1047
1442
|
this.configManager.set('showToolDetails', true);
|
|
1048
|
-
|
|
1443
|
+
this.configManager.save('global');
|
|
1049
1444
|
logger.success('Tool display mode switched to verbose mode', 'Will show complete tool call information');
|
|
1050
1445
|
}
|
|
1051
1446
|
else if (mode === 'simple' || mode === 'concise' || mode === 'false' || mode === 'off') {
|
|
1052
1447
|
this.configManager.set('showToolDetails', false);
|
|
1053
|
-
|
|
1448
|
+
this.configManager.save('global');
|
|
1054
1449
|
logger.success('Tool display mode switched to simple mode', 'Only show tool execution status');
|
|
1055
1450
|
}
|
|
1056
1451
|
else {
|
|
@@ -1059,6 +1454,8 @@ export class SlashCommandHandler {
|
|
|
1059
1454
|
}
|
|
1060
1455
|
async handleStats() {
|
|
1061
1456
|
logger.section('Session Statistics');
|
|
1457
|
+
const authConfig = this.configManager.getAuthConfig();
|
|
1458
|
+
logger.info(` Base URL: ${authConfig.baseUrl}`);
|
|
1062
1459
|
logger.info(` Execution Mode: ${this.configManager.getExecutionMode()}`);
|
|
1063
1460
|
logger.info(` Language: ${this.configManager.getLanguage()}`);
|
|
1064
1461
|
logger.info(` Checkpointing: ${this.checkpointManager.isEnabled() ? 'Enabled' : 'Disabled'}`);
|
|
@@ -1069,17 +1466,16 @@ export class SlashCommandHandler {
|
|
|
1069
1466
|
logger.warn('Theme switching not implemented yet', 'Check back later for updates');
|
|
1070
1467
|
}
|
|
1071
1468
|
async handleLanguage() {
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
]);
|
|
1469
|
+
const language = (await select({
|
|
1470
|
+
message: 'Select language:',
|
|
1471
|
+
options: [
|
|
1472
|
+
{ value: 'zh', label: 'Chinese' },
|
|
1473
|
+
{ value: 'en', label: 'English' },
|
|
1474
|
+
],
|
|
1475
|
+
}));
|
|
1476
|
+
if (typeof language === 'symbol') {
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1083
1479
|
this.configManager.setLanguage(language);
|
|
1084
1480
|
logger.success(`Language changed to: ${language === 'zh' ? 'Chinese' : 'English'}`, 'Restart CLI to apply changes');
|
|
1085
1481
|
}
|
|
@@ -1091,6 +1487,45 @@ export class SlashCommandHandler {
|
|
|
1091
1487
|
logger.link('Documentation', 'https://platform.xagent.cn/');
|
|
1092
1488
|
logger.link('GitHub', 'https://github.com/xagent-ai/xagent-cli');
|
|
1093
1489
|
}
|
|
1490
|
+
async handleUpdate() {
|
|
1491
|
+
const separator = icons.separator.repeat(Math.min(40, process.stdout.columns || 80));
|
|
1492
|
+
console.log('');
|
|
1493
|
+
console.log(colors.primaryBright(`${icons.rocket} Update Check`));
|
|
1494
|
+
console.log(colors.border(separator));
|
|
1495
|
+
console.log('');
|
|
1496
|
+
try {
|
|
1497
|
+
const { getUpdateManager } = await import('./update.js');
|
|
1498
|
+
const updateManager = getUpdateManager();
|
|
1499
|
+
const versionInfo = await updateManager.checkForUpdates();
|
|
1500
|
+
console.log(` ${icons.info} ${colors.textMuted('Current version:')} ${colors.primaryBright(versionInfo.currentVersion)}`);
|
|
1501
|
+
console.log(` ${icons.code} ${colors.textMuted('Latest version:')} ${colors.primaryBright(versionInfo.latestVersion)}`);
|
|
1502
|
+
console.log('');
|
|
1503
|
+
if (versionInfo.updateAvailable) {
|
|
1504
|
+
console.log(colors.success(` 📦 A new version is available!`));
|
|
1505
|
+
console.log('');
|
|
1506
|
+
if (versionInfo.releaseNotes) {
|
|
1507
|
+
console.log(colors.textMuted(' Release Notes:'));
|
|
1508
|
+
console.log(colors.textDim(` ${versionInfo.releaseNotes}`));
|
|
1509
|
+
console.log('');
|
|
1510
|
+
}
|
|
1511
|
+
const shouldUpdate = await confirm({
|
|
1512
|
+
message: 'Do you want to update now?',
|
|
1513
|
+
});
|
|
1514
|
+
if (shouldUpdate === true) {
|
|
1515
|
+
console.log('');
|
|
1516
|
+
await updateManager.autoUpdate();
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
else {
|
|
1520
|
+
console.log(colors.success(` ✅ You are using the latest version`));
|
|
1521
|
+
console.log('');
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
catch (error) {
|
|
1525
|
+
console.log(colors.error(` ❌ Failed to check for updates: ${error.message}`));
|
|
1526
|
+
console.log('');
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1094
1529
|
async handleCompress(args) {
|
|
1095
1530
|
const config = this.configManager.getContextCompressionConfig();
|
|
1096
1531
|
// If there are arguments, process config or execute
|
|
@@ -1106,15 +1541,11 @@ export class SlashCommandHandler {
|
|
|
1106
1541
|
// Display current configuration
|
|
1107
1542
|
console.log(chalk.cyan('\n📦 Context Compression:\n'));
|
|
1108
1543
|
console.log(` Status: ${config.enabled ? chalk.green('Enabled') : chalk.red('Disabled')}`);
|
|
1109
|
-
console.log(` Max Messages: ${chalk.yellow(config.maxMessages.toString())}`);
|
|
1110
|
-
console.log(` Max Tokens: ${chalk.yellow(config.maxContextSize.toString())}`);
|
|
1111
1544
|
console.log('');
|
|
1112
1545
|
console.log(chalk.gray('Usage:'));
|
|
1113
1546
|
console.log(chalk.gray(' /compress - Show current configuration'));
|
|
1114
1547
|
console.log(chalk.gray(' /compress exec - Execute compression now'));
|
|
1115
1548
|
console.log(chalk.gray(' /compress on|off - Enable/disable compression'));
|
|
1116
|
-
console.log(chalk.gray(' /compress max_message <n> - Set max messages before compression'));
|
|
1117
|
-
console.log(chalk.gray(' /compress max_token <n> - Set max tokens before compression'));
|
|
1118
1549
|
console.log('');
|
|
1119
1550
|
}
|
|
1120
1551
|
async executeCompression(config) {
|
|
@@ -1133,7 +1564,7 @@ export class SlashCommandHandler {
|
|
|
1133
1564
|
const spinner = ora({
|
|
1134
1565
|
text: 'Compressing context...',
|
|
1135
1566
|
spinner: 'dots',
|
|
1136
|
-
color: 'cyan'
|
|
1567
|
+
color: 'cyan',
|
|
1137
1568
|
}).start();
|
|
1138
1569
|
try {
|
|
1139
1570
|
const result = await this.contextCompressor.compressContext(messages, 'You are a helpful AI assistant.', config);
|
|
@@ -1159,50 +1590,235 @@ export class SlashCommandHandler {
|
|
|
1159
1590
|
case 'on':
|
|
1160
1591
|
config.enabled = true;
|
|
1161
1592
|
this.configManager.setContextCompressionConfig(config);
|
|
1162
|
-
|
|
1593
|
+
this.configManager.save('global');
|
|
1163
1594
|
console.log(chalk.green('✅ Context compression enabled'));
|
|
1164
1595
|
break;
|
|
1165
1596
|
case 'off':
|
|
1166
1597
|
config.enabled = false;
|
|
1167
1598
|
this.configManager.setContextCompressionConfig(config);
|
|
1168
|
-
|
|
1599
|
+
this.configManager.save('global');
|
|
1169
1600
|
console.log(chalk.green('✅ Context compression disabled'));
|
|
1170
1601
|
break;
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1602
|
+
default:
|
|
1603
|
+
console.log(chalk.red(`❌ Unknown action: ${action}`));
|
|
1604
|
+
console.log(chalk.gray('Available actions: on, off, exec'));
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
async handleSkill(args) {
|
|
1608
|
+
const os = await import('os');
|
|
1609
|
+
const path = await import('path');
|
|
1610
|
+
const { fileURLToPath } = await import('url');
|
|
1611
|
+
const { promises: fs } = await import('fs');
|
|
1612
|
+
const action = args[0] || 'list';
|
|
1613
|
+
const userSkillsPath = this.configManager.getUserSkillsPath() || path.join(os.homedir(), '.xagent', 'skills');
|
|
1614
|
+
switch (action) {
|
|
1615
|
+
case 'list':
|
|
1616
|
+
await this.listUserSkills(userSkillsPath, fs, path);
|
|
1617
|
+
break;
|
|
1618
|
+
case 'add':
|
|
1619
|
+
await this.addSkill(args[1], userSkillsPath, fs, path);
|
|
1620
|
+
break;
|
|
1621
|
+
case 'remove':
|
|
1622
|
+
await this.removeSkill(args[1], userSkillsPath, fs, path);
|
|
1623
|
+
break;
|
|
1624
|
+
default:
|
|
1625
|
+
console.log(chalk.cyan('\n🔧 Skills:\n'));
|
|
1626
|
+
console.log(` Skills directory: ${chalk.yellow(userSkillsPath)}\n`);
|
|
1627
|
+
console.log(chalk.gray('Available commands:'));
|
|
1628
|
+
console.log(chalk.gray(' /skill list - List installed skills'));
|
|
1629
|
+
console.log(chalk.gray(' /skill add <source> - Add a skill (local path or remote URL)'));
|
|
1630
|
+
console.log(chalk.gray(' /skill remove <name> - Remove a user-installed skill'));
|
|
1631
|
+
console.log();
|
|
1632
|
+
console.log(chalk.gray('Examples:'));
|
|
1633
|
+
console.log(chalk.gray(' /skill add ./my-skill - Local path'));
|
|
1634
|
+
console.log(chalk.gray(' /skill add owner/repo - GitHub shorthand'));
|
|
1635
|
+
console.log(chalk.gray(' /skill add https://github.com/owner/repo - GitHub URL'));
|
|
1636
|
+
console.log();
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
async listUserSkills(userSkillsPath, fs, path) {
|
|
1640
|
+
console.log(chalk.cyan('\n🔧 Skills:\n'));
|
|
1641
|
+
try {
|
|
1642
|
+
const entries = await fs.readdir(userSkillsPath, { withFileTypes: true });
|
|
1643
|
+
const skills = entries.filter((e) => e.isDirectory());
|
|
1644
|
+
if (skills.length === 0) {
|
|
1645
|
+
console.log(chalk.gray(' No skills installed'));
|
|
1646
|
+
console.log(chalk.cyan('\n To add a skill, use:'));
|
|
1647
|
+
console.log(chalk.cyan(' /skill add <path-to-skill>\n'));
|
|
1648
|
+
return;
|
|
1649
|
+
}
|
|
1650
|
+
for (const skill of skills) {
|
|
1651
|
+
const skillPath = path.join(userSkillsPath, skill.name);
|
|
1652
|
+
const skillMdPath = path.join(skillPath, 'SKILL.md');
|
|
1653
|
+
try {
|
|
1654
|
+
const content = await fs.readFile(skillMdPath, 'utf-8');
|
|
1655
|
+
const nameMatch = content.match(/^name:\s*(.+)$/m);
|
|
1656
|
+
const descMatch = content.match(/^description:\s*(.+)$/m);
|
|
1657
|
+
const name = nameMatch ? nameMatch[1].trim() : skill.name;
|
|
1658
|
+
const description = descMatch ? descMatch[1].trim() : 'No description';
|
|
1659
|
+
console.log(` ${chalk.cyan('•')} ${chalk.yellow(name)}`);
|
|
1660
|
+
console.log(` ${chalk.gray(description)}`);
|
|
1661
|
+
console.log();
|
|
1662
|
+
}
|
|
1663
|
+
catch {
|
|
1664
|
+
console.log(` ${chalk.cyan('•')} ${chalk.yellow(skill.name)}`);
|
|
1665
|
+
console.log(` ${chalk.gray('(Missing SKILL.md)')}`);
|
|
1666
|
+
console.log();
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
console.log(chalk.gray(` Skills directory: ${userSkillsPath}`));
|
|
1670
|
+
console.log();
|
|
1671
|
+
}
|
|
1672
|
+
catch (error) {
|
|
1673
|
+
if (error.code === 'ENOENT') {
|
|
1674
|
+
console.log(chalk.gray(' No skills installed'));
|
|
1675
|
+
console.log(chalk.cyan('\n To add a skill, use:'));
|
|
1676
|
+
console.log(chalk.cyan(' /skill add <path-to-skill>\n'));
|
|
1677
|
+
}
|
|
1678
|
+
else {
|
|
1679
|
+
console.log(chalk.red(` Error: ${error.message}`));
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
async addSkill(source, userSkillsPath, fs, path) {
|
|
1684
|
+
if (!source) {
|
|
1685
|
+
console.log(chalk.yellow('\n⚠️ Please specify a skill source'));
|
|
1686
|
+
console.log(chalk.cyan(' Usage: /skill add <source>\n'));
|
|
1687
|
+
console.log(chalk.gray(' Examples:'));
|
|
1688
|
+
console.log(chalk.gray(' /skill add ./my-skill - Local path'));
|
|
1689
|
+
console.log(chalk.gray(' /skill add owner/repo - GitHub shorthand'));
|
|
1690
|
+
console.log(chalk.gray(' /skill add https://github.com/owner/repo'));
|
|
1691
|
+
console.log();
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
const { parseSource, installSkill } = await import('./skill-installer.js');
|
|
1695
|
+
const parsed = parseSource(source.trim());
|
|
1696
|
+
const isLocal = parsed.type === 'local';
|
|
1697
|
+
if (isLocal) {
|
|
1698
|
+
// Local installation
|
|
1699
|
+
const resolvedPath = path.resolve(source);
|
|
1700
|
+
const skillName = path.basename(resolvedPath);
|
|
1701
|
+
const destPath = path.join(userSkillsPath, skillName);
|
|
1702
|
+
try {
|
|
1703
|
+
// Check if source exists
|
|
1704
|
+
await fs.access(resolvedPath);
|
|
1705
|
+
// Check if SKILL.md exists
|
|
1706
|
+
const skillMdPath = path.join(resolvedPath, 'SKILL.md');
|
|
1707
|
+
try {
|
|
1708
|
+
await fs.access(skillMdPath);
|
|
1709
|
+
}
|
|
1710
|
+
catch {
|
|
1711
|
+
console.log(chalk.red(`\n❌ SKILL.md not found in ${resolvedPath}`));
|
|
1712
|
+
console.log(chalk.gray(' Each skill must have a SKILL.md file\n'));
|
|
1713
|
+
return;
|
|
1714
|
+
}
|
|
1715
|
+
// Check if skill already exists
|
|
1716
|
+
try {
|
|
1717
|
+
await fs.access(destPath);
|
|
1718
|
+
console.log(chalk.yellow(`\n⚠️ Skill "${skillName}" already installed`));
|
|
1719
|
+
console.log(chalk.cyan(` Use: /skill remove ${skillName} to remove it first\n`));
|
|
1720
|
+
return;
|
|
1721
|
+
}
|
|
1722
|
+
catch {
|
|
1723
|
+
// Doesn't exist, proceed
|
|
1724
|
+
}
|
|
1725
|
+
// Ensure skills directory exists
|
|
1726
|
+
await fs.mkdir(userSkillsPath, { recursive: true });
|
|
1727
|
+
// Copy the skill
|
|
1728
|
+
await this.copyDirectory(resolvedPath, destPath);
|
|
1729
|
+
console.log(chalk.green('\n✅ Skill installed successfully'));
|
|
1730
|
+
console.log(chalk.gray(` Name: ${skillName}`));
|
|
1731
|
+
console.log(chalk.gray(` Location: ${destPath}`));
|
|
1732
|
+
console.log(chalk.gray(` Type: Local`));
|
|
1733
|
+
console.log();
|
|
1734
|
+
// Trigger system prompt update
|
|
1735
|
+
this.onSystemPromptUpdate?.();
|
|
1736
|
+
}
|
|
1737
|
+
catch (error) {
|
|
1738
|
+
if (error.code === 'ENOENT') {
|
|
1739
|
+
console.log(chalk.red(`\n❌ Skill not found: ${source}\n`));
|
|
1182
1740
|
}
|
|
1183
1741
|
else {
|
|
1184
|
-
console.log(chalk.
|
|
1742
|
+
console.log(chalk.red(`\n❌ Error installing skill: ${error.message}\n`));
|
|
1185
1743
|
}
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
console.log(chalk.green(
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
else {
|
|
1747
|
+
// Remote installation
|
|
1748
|
+
console.log(chalk.cyan('\n📦 Installing skill from remote source...\n'));
|
|
1749
|
+
console.log(chalk.gray(` Source: ${source}`));
|
|
1750
|
+
console.log(chalk.gray(` Type: Remote`));
|
|
1751
|
+
console.log();
|
|
1752
|
+
try {
|
|
1753
|
+
const result = await installSkill(source);
|
|
1754
|
+
if (result.success) {
|
|
1755
|
+
console.log(chalk.green('✅ Skill installed successfully'));
|
|
1756
|
+
console.log(chalk.gray(` Name: ${result.skillName}`));
|
|
1757
|
+
console.log(chalk.gray(` Location: ${result.skillPath}`));
|
|
1758
|
+
console.log(chalk.gray(' Type: Remote'));
|
|
1759
|
+
console.log();
|
|
1760
|
+
// Trigger system prompt update - skill is immediately available
|
|
1761
|
+
this.onSystemPromptUpdate?.();
|
|
1198
1762
|
}
|
|
1199
1763
|
else {
|
|
1200
|
-
console.log(chalk.
|
|
1764
|
+
console.log(chalk.red(`\n❌ Failed to install skill: ${result.error}\n`));
|
|
1201
1765
|
}
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
console.log(chalk.red(
|
|
1205
|
-
|
|
1766
|
+
}
|
|
1767
|
+
catch (error) {
|
|
1768
|
+
console.log(chalk.red(`\n❌ Error installing skill: ${error.message}\n`));
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
async removeSkill(skillName, userSkillsPath, fs, path) {
|
|
1773
|
+
if (!skillName) {
|
|
1774
|
+
console.log(chalk.yellow('\n⚠️ Please specify a skill name'));
|
|
1775
|
+
console.log(chalk.cyan(' Usage: /skill remove <skill-name>\n'));
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1778
|
+
// Protect find-skills from deletion
|
|
1779
|
+
if (skillName === 'find-skills') {
|
|
1780
|
+
console.log(chalk.red('\n❌ Cannot remove protected skill: find-skills'));
|
|
1781
|
+
console.log(chalk.gray(' find-skills is a built-in skill that helps you discover and install other skills.\n'));
|
|
1782
|
+
return;
|
|
1783
|
+
}
|
|
1784
|
+
const skillPath = path.join(userSkillsPath, skillName);
|
|
1785
|
+
try {
|
|
1786
|
+
await fs.access(skillPath);
|
|
1787
|
+
// Verify it's in skills path
|
|
1788
|
+
if (!skillPath.startsWith(userSkillsPath)) {
|
|
1789
|
+
console.log(chalk.red(`\n❌ Cannot remove skill outside user directory\n`));
|
|
1790
|
+
return;
|
|
1791
|
+
}
|
|
1792
|
+
// Remove the skill directory
|
|
1793
|
+
await fs.rm(skillPath, { recursive: true, force: true });
|
|
1794
|
+
console.log(chalk.green('\n✅ Skill removed successfully'));
|
|
1795
|
+
console.log();
|
|
1796
|
+
// Trigger system prompt update
|
|
1797
|
+
this.onSystemPromptUpdate?.();
|
|
1798
|
+
}
|
|
1799
|
+
catch (error) {
|
|
1800
|
+
if (error.code === 'ENOENT' || error.code === 'ENOENT') {
|
|
1801
|
+
console.log(chalk.yellow(`\n⚠️ Skill not found: ${skillName}\n`));
|
|
1802
|
+
}
|
|
1803
|
+
else {
|
|
1804
|
+
console.log(chalk.red(`\n❌ Error removing skill: ${error.message}\n`));
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
async copyDirectory(src, dest) {
|
|
1809
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
1810
|
+
await fs.mkdir(dest, { recursive: true });
|
|
1811
|
+
for (const entry of entries) {
|
|
1812
|
+
// Skip node_modules to keep dependencies isolated
|
|
1813
|
+
// if (entry.name === 'node_modules') continue;
|
|
1814
|
+
const srcPath = path.join(src, entry.name);
|
|
1815
|
+
const destPath = path.join(dest, entry.name);
|
|
1816
|
+
if (entry.isDirectory()) {
|
|
1817
|
+
await this.copyDirectory(srcPath, destPath);
|
|
1818
|
+
}
|
|
1819
|
+
else if (entry.isFile()) {
|
|
1820
|
+
await fs.copyFile(srcPath, destPath);
|
|
1821
|
+
}
|
|
1206
1822
|
}
|
|
1207
1823
|
}
|
|
1208
1824
|
}
|