@xagent-ai/cli 1.2.2 → 1.3.1
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/release.yml +76 -0
- package/.github/workflows/ci.yml +75 -0
- package/.github/workflows/release.yml +103 -0
- package/.gitmodules +3 -3
- package/README.md +326 -280
- package/README_CN.md +325 -279
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +7 -3
- package/dist/agents.js.map +1 -1
- package/dist/ai-client/factory.d.ts +40 -0
- package/dist/ai-client/factory.d.ts.map +1 -0
- package/dist/ai-client/factory.js +100 -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 +406 -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 +290 -0
- package/dist/ai-client/providers/openai.js.map +1 -0
- package/dist/ai-client/providers/remote.d.ts +110 -0
- package/dist/ai-client/providers/remote.d.ts.map +1 -0
- package/dist/ai-client/providers/remote.js +352 -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 +274 -0
- package/dist/ai-client/types.d.ts.map +1 -0
- package/dist/ai-client/types.js +90 -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 +164 -174
- 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 +53 -32
- package/dist/cancellation.js.map +1 -1
- package/dist/checkpoint.d.ts +2 -1
- package/dist/checkpoint.d.ts.map +1 -1
- package/dist/checkpoint.js +39 -6
- package/dist/checkpoint.js.map +1 -1
- package/dist/cli.js +742 -29
- 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 +82 -18
- package/dist/context-compressor.d.ts.map +1 -1
- package/dist/context-compressor.js +718 -154
- package/dist/context-compressor.js.map +1 -1
- package/dist/conversation.d.ts +1 -1
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +8 -7
- package/dist/conversation.js.map +1 -1
- package/dist/gui-subagent/action-parser/actionParser.d.ts.map +1 -1
- package/dist/gui-subagent/action-parser/actionParser.js +6 -4
- package/dist/gui-subagent/action-parser/actionParser.js.map +1 -1
- package/dist/gui-subagent/agent/gui-agent.d.ts +39 -2
- package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -1
- package/dist/gui-subagent/agent/gui-agent.js +189 -74
- package/dist/gui-subagent/agent/gui-agent.js.map +1 -1
- package/dist/gui-subagent/index.d.ts +23 -1
- package/dist/gui-subagent/index.d.ts.map +1 -1
- package/dist/gui-subagent/index.js +6 -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 +31 -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 +8 -5
- package/dist/input-processor.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/mcp.d.ts +7 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +157 -49
- package/dist/mcp.js.map +1 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +3 -3
- package/dist/memory.js.map +1 -1
- package/dist/output-util.d.ts +27 -0
- package/dist/output-util.d.ts.map +1 -0
- package/dist/output-util.js +74 -0
- package/dist/output-util.js.map +1 -0
- package/dist/retry.js +1 -1
- package/dist/retry.js.map +1 -1
- package/dist/ripgrep.d.ts +29 -0
- package/dist/ripgrep.d.ts.map +1 -0
- package/dist/ripgrep.js +294 -0
- package/dist/ripgrep.js.map +1 -0
- package/dist/sdk-output-adapter.d.ts +34 -1
- package/dist/sdk-output-adapter.d.ts.map +1 -1
- package/dist/sdk-output-adapter.js +67 -2
- package/dist/sdk-output-adapter.js.map +1 -1
- package/dist/sdk-session.d.ts.map +1 -1
- package/dist/sdk-session.js +2 -0
- package/dist/sdk-session.js.map +1 -1
- package/dist/session-manager.js +3 -3
- package/dist/session-manager.js.map +1 -1
- package/dist/session.d.ts +116 -6
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +1416 -448
- 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 +126 -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 +8 -2
- package/dist/skill-invoker.d.ts.map +1 -1
- package/dist/skill-invoker.js +36 -15
- 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 +51 -48
- 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 +341 -0
- package/dist/skill-manager.js.map +1 -0
- package/dist/slash-commands.d.ts +39 -2
- package/dist/slash-commands.d.ts.map +1 -1
- package/dist/slash-commands.js +934 -305
- package/dist/slash-commands.js.map +1 -1
- package/dist/smart-approval.d.ts +20 -1
- package/dist/smart-approval.d.ts.map +1 -1
- package/dist/smart-approval.js +125 -56
- 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 +86 -36
- 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/theme.d.ts.map +1 -1
- package/dist/theme.js +8 -7
- package/dist/theme.js.map +1 -1
- package/dist/tools.d.ts +38 -7
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +1249 -617
- 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 +84 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +49 -0
- package/dist/types.js.map +1 -1
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +28 -36
- 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 +61 -49
- 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 +440 -439
- package/find-skills/SKILL.md +133 -0
- package/package.json +91 -90
- package/scripts/install-ripgrep.js +241 -0
- package/src/agents.ts +7 -3
- package/src/ai-client/factory.ts +116 -0
- package/src/ai-client/index.ts +61 -0
- package/src/ai-client/providers/anthropic.ts +475 -0
- package/src/ai-client/providers/openai.ts +348 -0
- package/src/ai-client/providers/remote.ts +439 -0
- package/src/ai-client/registry.ts +97 -0
- package/src/ai-client/types.ts +364 -0
- package/src/ai-client-factory.ts +204 -0
- package/src/auth.ts +661 -614
- package/src/cancellation.ts +202 -176
- package/src/checkpoint.ts +255 -219
- package/src/cli.ts +1523 -743
- package/src/config.ts +341 -297
- package/src/context-compressor.ts +987 -290
- package/src/conversation.ts +290 -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 +1234 -1089
- package/src/gui-subagent/agent/index.ts +5 -5
- package/src/gui-subagent/index.ts +185 -163
- package/src/gui-subagent/operator/base-operator.ts +244 -245
- package/src/gui-subagent/operator/computer-operator.ts +541 -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 +8 -5
- package/src/logger.ts +436 -438
- package/src/mcp.ts +793 -682
- package/src/memory.ts +343 -344
- package/src/output-util.ts +80 -0
- package/src/retry.ts +1 -1
- package/src/ripgrep.ts +370 -0
- package/src/sdk-output-adapter.ts +842 -0
- package/src/sdk-session.ts +62 -0
- package/src/session-manager.ts +308 -308
- package/src/session.ts +1775 -573
- package/src/shell.ts +134 -0
- package/src/skill-installer.ts +518 -0
- package/src/skill-invoker.ts +959 -935
- package/src/skill-loader.ts +501 -496
- package/src/skill-manager.ts +385 -0
- package/src/slash-commands.ts +2189 -1389
- package/src/smart-approval.ts +193 -74
- package/src/system-prompt-generator.ts +91 -36
- package/src/terminal.ts +96 -0
- package/src/theme.ts +739 -738
- package/src/tools.ts +1790 -931
- package/src/truncate.ts +173 -0
- package/src/types.ts +337 -198
- package/src/update.ts +33 -40
- package/src/workflow.ts +521 -508
- package/test/cli-launch.test.ts +279 -0
- package/tsconfig.json +22 -22
- package/vitest.config.ts +21 -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-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/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/{.eslintrc.js → .eslintrc.cjs} +0 -0
package/src/cli.ts
CHANGED
|
@@ -1,743 +1,1523 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import
|
|
5
|
-
import { startInteractiveSession } from './session.js';
|
|
6
|
-
import { getConfigManager } from './config.js';
|
|
7
|
-
import { AuthService, selectAuthType } from './auth.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
//
|
|
69
|
-
if (errorMessage.includes('
|
|
70
|
-
return {
|
|
71
|
-
message: '
|
|
72
|
-
suggestion: 'Please
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
console.log('');
|
|
273
|
-
console.log(
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
console.log(colors.
|
|
315
|
-
console.log(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
console.log(colors.
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
if (
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
console.log(colors.
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
if (
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
.
|
|
526
|
-
.
|
|
527
|
-
|
|
528
|
-
.
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
console.log(colors.
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
console.log(
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
//
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { confirm } from '@clack/prompts';
|
|
5
|
+
import { startInteractiveSession } from './session.js';
|
|
6
|
+
import { getConfigManager } from './config.js';
|
|
7
|
+
import { AuthService, selectAuthType } from './auth.js';
|
|
8
|
+
import { AuthType } from './types.js';
|
|
9
|
+
import { fetchDefaultModels } from './ai-client/providers/remote.js';
|
|
10
|
+
import { getAgentManager } from './agents.js';
|
|
11
|
+
import { getMCPManager } from './mcp.js';
|
|
12
|
+
import { setConfigProvider } from './logger.js';
|
|
13
|
+
import { icons, colors } from './theme.js';
|
|
14
|
+
import { getCancellationManager } from './cancellation.js';
|
|
15
|
+
import { readFileSync, promises as fs } from 'fs';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import { dirname, join } from 'path';
|
|
18
|
+
import { fileURLToPath } from 'url';
|
|
19
|
+
|
|
20
|
+
// Get current directory
|
|
21
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
22
|
+
const __dirname = dirname(__filename);
|
|
23
|
+
|
|
24
|
+
// State file for skill updates (used to notify running xAgent)
|
|
25
|
+
const SKILL_STATE_FILE = '.skill-state.json';
|
|
26
|
+
|
|
27
|
+
function getSkillStateFilePath(userSkillsPath: string): string {
|
|
28
|
+
return path.join(userSkillsPath, SKILL_STATE_FILE);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function notifySkillUpdate(userSkillsPath: string): Promise<void> {
|
|
32
|
+
try {
|
|
33
|
+
const stateFilePath = getSkillStateFilePath(userSkillsPath);
|
|
34
|
+
const timestamp = Date.now();
|
|
35
|
+
const state = { lastSkillUpdate: timestamp };
|
|
36
|
+
|
|
37
|
+
await fs.writeFile(stateFilePath, JSON.stringify(state, null, 2), 'utf-8');
|
|
38
|
+
|
|
39
|
+
console.log(colors.textMuted(' ℹ️ Skills updated for running xAgent sessions'));
|
|
40
|
+
} catch {
|
|
41
|
+
// Silent fail - notification is optional
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Read package.json
|
|
46
|
+
const packageJsonPath = join(__dirname, '../package.json');
|
|
47
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
48
|
+
|
|
49
|
+
// Initialize CancellationManager early to set up ESC handler
|
|
50
|
+
getCancellationManager();
|
|
51
|
+
|
|
52
|
+
// Set up config provider for logger to read loggerLevel
|
|
53
|
+
setConfigProvider(() => {
|
|
54
|
+
const configManager = getConfigManager();
|
|
55
|
+
return {
|
|
56
|
+
getLoggerLevel: () => configManager.getLoggerLevel()
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const program = new Command();
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Format error message for user-friendly display
|
|
64
|
+
*/
|
|
65
|
+
function formatError(error: unknown): { message: string; suggestion: string } {
|
|
66
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
67
|
+
|
|
68
|
+
// Network errors
|
|
69
|
+
if (errorMessage.includes('ENOTFOUND') || errorMessage.includes('ECONNREFUSED')) {
|
|
70
|
+
return {
|
|
71
|
+
message: 'Unable to connect to the server',
|
|
72
|
+
suggestion: 'Please check your network connection and try again.'
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (errorMessage.includes('ETIMEDOUT') || errorMessage.includes('ECONNRESET')) {
|
|
76
|
+
return {
|
|
77
|
+
message: 'Connection timed out',
|
|
78
|
+
suggestion: 'The server may be busy. Please wait a moment and try again.'
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// Authentication errors
|
|
82
|
+
if (errorMessage.includes('401') || errorMessage.includes('Unauthorized') || errorMessage.includes('invalid token')) {
|
|
83
|
+
return {
|
|
84
|
+
message: 'Authentication failed',
|
|
85
|
+
suggestion: 'Please login again using: xagent auth'
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Token expired
|
|
89
|
+
if (errorMessage.includes('token') && errorMessage.includes('expired')) {
|
|
90
|
+
return {
|
|
91
|
+
message: 'Session expired',
|
|
92
|
+
suggestion: 'Please login again using: xagent auth'
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// Permission errors
|
|
96
|
+
if (errorMessage.includes('EACCES') || errorMessage.includes('permission denied')) {
|
|
97
|
+
return {
|
|
98
|
+
message: 'Permission denied',
|
|
99
|
+
suggestion: 'Please check your file permissions or run with appropriate privileges.'
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// File not found
|
|
103
|
+
if (errorMessage.includes('ENOENT') || errorMessage.includes('not found')) {
|
|
104
|
+
return {
|
|
105
|
+
message: 'File or resource not found',
|
|
106
|
+
suggestion: 'Please check the path and try again.'
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// Invalid JSON
|
|
110
|
+
if (errorMessage.includes('JSON') || errorMessage.includes('parse')) {
|
|
111
|
+
return {
|
|
112
|
+
message: 'Invalid data format',
|
|
113
|
+
suggestion: 'The configuration file may be corrupted. Please check the file content.'
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// User cancellation - no suggestion needed
|
|
118
|
+
if (errorMessage.includes('cancelled by user') || errorMessage.includes('Operation cancelled')) {
|
|
119
|
+
return {
|
|
120
|
+
message: 'Operation cancelled',
|
|
121
|
+
suggestion: ''
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Default friendly message
|
|
126
|
+
return {
|
|
127
|
+
message: 'An error occurred',
|
|
128
|
+
suggestion: 'Please try again. If the problem persists, check your configuration.'
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Recursively copy a directory
|
|
134
|
+
*/
|
|
135
|
+
async function copyDirectory(src: string, dest: string): Promise<void> {
|
|
136
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
137
|
+
|
|
138
|
+
await fs.mkdir(dest, { recursive: true });
|
|
139
|
+
|
|
140
|
+
for (const entry of entries) {
|
|
141
|
+
// Skip node_modules to keep dependencies isolated
|
|
142
|
+
// if (entry.name === 'node_modules') continue;
|
|
143
|
+
|
|
144
|
+
const srcPath = path.join(src, entry.name);
|
|
145
|
+
const destPath = path.join(dest, entry.name);
|
|
146
|
+
|
|
147
|
+
if (entry.isDirectory()) {
|
|
148
|
+
await copyDirectory(srcPath, destPath);
|
|
149
|
+
} else if (entry.isFile()) {
|
|
150
|
+
await fs.copyFile(srcPath, destPath);
|
|
151
|
+
}
|
|
152
|
+
// Skip symbolic links for simplicity
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
program
|
|
157
|
+
.name('xagent')
|
|
158
|
+
.description('AI-powered command-line assistant')
|
|
159
|
+
.version(packageJson.version)
|
|
160
|
+
.option('-h, --help', 'Show help');
|
|
161
|
+
|
|
162
|
+
program
|
|
163
|
+
.command('start')
|
|
164
|
+
.description('Start the xAgent CLI interactive session')
|
|
165
|
+
.option('--approval-mode <mode>', 'Set approval mode (yolo, accept_edits, plan, default, smart)')
|
|
166
|
+
.option('--sdk', 'Run in SDK mode for programmatic access (stdin/stdout JSON communication)')
|
|
167
|
+
.action(async (options) => {
|
|
168
|
+
// Check if running in SDK mode
|
|
169
|
+
if (options.sdk || process.env.XAGENT_SDK === 'true') {
|
|
170
|
+
const { startSdkSession } = await import('./sdk-session.js');
|
|
171
|
+
await startSdkSession();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (options.approvalMode) {
|
|
176
|
+
const { getConfigManager } = await import('./config.js');
|
|
177
|
+
const { ExecutionMode } = await import('./types.js');
|
|
178
|
+
const configManager = getConfigManager();
|
|
179
|
+
|
|
180
|
+
const validModes = Object.values(ExecutionMode) as string[];
|
|
181
|
+
if (!validModes.includes(options.approvalMode)) {
|
|
182
|
+
console.log('');
|
|
183
|
+
console.log(colors.error(`Invalid approval mode: ${options.approvalMode}`));
|
|
184
|
+
console.log(colors.textMuted(`Valid modes: ${validModes.join(', ')}`));
|
|
185
|
+
console.log('');
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
configManager.setApprovalMode(options.approvalMode as any);
|
|
190
|
+
configManager.save('global');
|
|
191
|
+
console.log('');
|
|
192
|
+
console.log(colors.success(`✅ Approval mode set to: ${options.approvalMode}`));
|
|
193
|
+
console.log('');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
await startInteractiveSession();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
program
|
|
200
|
+
.command('auth')
|
|
201
|
+
.description('Configure authentication for xAgent CLI')
|
|
202
|
+
.action(async () => {
|
|
203
|
+
const separator = icons.separator.repeat(40);
|
|
204
|
+
console.log('');
|
|
205
|
+
console.log(colors.primaryBright(`${icons.lock} Authentication Management`));
|
|
206
|
+
console.log(colors.border(separator));
|
|
207
|
+
console.log('');
|
|
208
|
+
|
|
209
|
+
const authType = await selectAuthType();
|
|
210
|
+
const configManager = getConfigManager();
|
|
211
|
+
configManager.set('selectedAuthType', authType);
|
|
212
|
+
|
|
213
|
+
// Get xagentApiBaseUrl from config (respects XAGENT_BASE_URL env var)
|
|
214
|
+
const config = configManager.getAuthConfig();
|
|
215
|
+
|
|
216
|
+
const authService = new AuthService({
|
|
217
|
+
type: authType,
|
|
218
|
+
apiKey: '',
|
|
219
|
+
baseUrl: '',
|
|
220
|
+
modelName: '',
|
|
221
|
+
xagentApiBaseUrl: config.xagentApiBaseUrl
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const success = await authService.authenticate();
|
|
225
|
+
|
|
226
|
+
if (success) {
|
|
227
|
+
const authConfig = authService.getAuthConfig();
|
|
228
|
+
|
|
229
|
+
// Clear modelName for remote mode
|
|
230
|
+
if (authType === AuthType.OAUTH_XAGENT) {
|
|
231
|
+
authConfig.modelName = '';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
configManager.setAuthConfig(authConfig);
|
|
235
|
+
|
|
236
|
+
// Set default remote model settings if not already set
|
|
237
|
+
if (authType === AuthType.OAUTH_XAGENT) {
|
|
238
|
+
const webBaseUrl = authConfig.xagentApiBaseUrl || 'https://www.xagent-colife.net';
|
|
239
|
+
let defaultLlmName = '';
|
|
240
|
+
let defaultVlmName = '';
|
|
241
|
+
|
|
242
|
+
try {
|
|
243
|
+
console.log(colors.textMuted(' Fetching default models from remote server...'));
|
|
244
|
+
const defaults = await fetchDefaultModels(authConfig.apiKey || '', webBaseUrl);
|
|
245
|
+
|
|
246
|
+
if (defaults.llm?.name) {
|
|
247
|
+
defaultLlmName = defaults.llm.name;
|
|
248
|
+
console.log(colors.textMuted(` Default LLM: ${defaults.llm.displayName || defaultLlmName}`));
|
|
249
|
+
}
|
|
250
|
+
if (defaults.vlm?.name) {
|
|
251
|
+
defaultVlmName = defaults.vlm.name;
|
|
252
|
+
console.log(colors.textMuted(` Default VLM: ${defaults.vlm.displayName || defaultVlmName}`));
|
|
253
|
+
}
|
|
254
|
+
} catch (error: any) {
|
|
255
|
+
console.log(colors.textMuted(` ⚠️ Failed to fetch default models: ${error.message}`));
|
|
256
|
+
console.log(colors.textMuted(' ⚠️ Use /model command to select models manually.'));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
configManager.set('remote_llmModelName', defaultLlmName);
|
|
260
|
+
configManager.set('remote_vlmModelName', defaultVlmName);
|
|
261
|
+
configManager.save('global');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
console.log('');
|
|
265
|
+
console.log(colors.success('Authentication configured successfully!'));
|
|
266
|
+
console.log(colors.textMuted('You can now run "xagent start" to begin'));
|
|
267
|
+
console.log('');
|
|
268
|
+
process.exit(0);
|
|
269
|
+
} else {
|
|
270
|
+
console.log('');
|
|
271
|
+
console.log(colors.error('Authentication failed. Please try again.'));
|
|
272
|
+
console.log(colors.textMuted('Run "xagent auth" to retry'));
|
|
273
|
+
console.log('');
|
|
274
|
+
process.exit(1);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
program
|
|
279
|
+
.command('agent')
|
|
280
|
+
.description('Add, list, or remove SubAgents')
|
|
281
|
+
.option('-l, --list', 'List all agents')
|
|
282
|
+
.option('-a, --add <name>', 'Add a new agent')
|
|
283
|
+
.option('-r, --remove <name>', 'Remove an agent')
|
|
284
|
+
.option('--scope <scope>', 'Scope (global or project)', 'global')
|
|
285
|
+
.action(async (options) => {
|
|
286
|
+
const agentManager = getAgentManager(process.cwd());
|
|
287
|
+
await agentManager.loadAgents();
|
|
288
|
+
|
|
289
|
+
if (options.list) {
|
|
290
|
+
const agents = agentManager.getAllAgents();
|
|
291
|
+
|
|
292
|
+
if (agents.length === 0) {
|
|
293
|
+
console.log('');
|
|
294
|
+
console.log(colors.warning('No agents configured'));
|
|
295
|
+
console.log(colors.textMuted('Use /agents install in interactive mode to add agents'));
|
|
296
|
+
console.log('');
|
|
297
|
+
} else {
|
|
298
|
+
const separator = icons.separator.repeat(40);
|
|
299
|
+
console.log('');
|
|
300
|
+
console.log(colors.primaryBright(`${icons.robot} Available Agents`));
|
|
301
|
+
console.log(colors.border(separator));
|
|
302
|
+
console.log('');
|
|
303
|
+
|
|
304
|
+
agents.forEach((agent, index) => {
|
|
305
|
+
console.log(` ${colors.primaryBright(`${index + 1}. ${agent.agentType}`)}`);
|
|
306
|
+
console.log(` ${colors.textDim(` ${agent.whenToUse}`)}`);
|
|
307
|
+
console.log('');
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
process.exit(0);
|
|
311
|
+
} else if (options.add) {
|
|
312
|
+
console.log('');
|
|
313
|
+
console.log(colors.warning('Agent creation wizard not implemented yet'));
|
|
314
|
+
console.log(colors.textMuted('Use /agents install in interactive mode'));
|
|
315
|
+
console.log('');
|
|
316
|
+
} else if (options.remove) {
|
|
317
|
+
try {
|
|
318
|
+
await agentManager.removeAgent(options.remove, options.scope);
|
|
319
|
+
console.log('');
|
|
320
|
+
console.log(colors.success(`Agent ${options.remove} removed successfully`));
|
|
321
|
+
console.log('');
|
|
322
|
+
} catch (error: any) {
|
|
323
|
+
const { message, suggestion } = formatError(error);
|
|
324
|
+
console.log('');
|
|
325
|
+
console.log(colors.error(`Failed to remove agent: ${message}`));
|
|
326
|
+
console.log(colors.textMuted(suggestion));
|
|
327
|
+
console.log('');
|
|
328
|
+
}
|
|
329
|
+
} else {
|
|
330
|
+
console.log('');
|
|
331
|
+
console.log(colors.warning('Please specify an action: --list, --add, or --remove'));
|
|
332
|
+
console.log('');
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
program
|
|
337
|
+
.command('mcp')
|
|
338
|
+
.description('Add, list, get, or remove MCP servers')
|
|
339
|
+
.option('-l, --list', 'List all MCP servers')
|
|
340
|
+
.option('-g, --get <name>', 'Get details of a specific MCP server')
|
|
341
|
+
.option('-a, --add [name]', 'Add a new MCP server (interactive if no name provided)')
|
|
342
|
+
.option('-r, --remove <name>', 'Remove an MCP server')
|
|
343
|
+
.option('--scope <scope>', 'Scope (global or project)', 'global')
|
|
344
|
+
.option('-t, --transport <type>', 'Transport type: stdio, http')
|
|
345
|
+
.option('-c, --command <cmd>', 'Command for stdio transport')
|
|
346
|
+
.option('--args <args>', 'Arguments for stdio transport (comma-separated)')
|
|
347
|
+
.option('-u, --url <url>', 'URL for HTTP transport')
|
|
348
|
+
.option('-k, --token <token>', 'Authentication token (Bearer)')
|
|
349
|
+
.option('--header <headers>', 'Custom headers (can be used multiple times)')
|
|
350
|
+
.option('-y, --yes', 'Skip confirmation')
|
|
351
|
+
.action(async (options) => {
|
|
352
|
+
if (options.help) {
|
|
353
|
+
program.parse(['node', 'mcp', '--help']);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const configManager = getConfigManager(process.cwd());
|
|
358
|
+
configManager.load(); // Load config from file
|
|
359
|
+
const mcpManager = getMCPManager();
|
|
360
|
+
|
|
361
|
+
// Register all MCP servers from config to manager (for --list and --remove)
|
|
362
|
+
const mcpServers = configManager.getMcpServers();
|
|
363
|
+
Object.entries(mcpServers).forEach(([name, config]) => {
|
|
364
|
+
mcpManager.registerServer(name, config);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
if (options.list) {
|
|
368
|
+
const mcpServers = configManager.getMcpServers();
|
|
369
|
+
const serverNames = Object.keys(mcpServers);
|
|
370
|
+
|
|
371
|
+
if (serverNames.length === 0) {
|
|
372
|
+
console.log('');
|
|
373
|
+
console.log(colors.warning('No MCP servers configured'));
|
|
374
|
+
console.log(colors.textMuted('Use "xagent mcp --add" to add servers'));
|
|
375
|
+
console.log('');
|
|
376
|
+
} else {
|
|
377
|
+
console.log(colors.textMuted('Connecting to MCP servers...'));
|
|
378
|
+
|
|
379
|
+
for (const name of serverNames) {
|
|
380
|
+
try {
|
|
381
|
+
await mcpManager.connectServer(name);
|
|
382
|
+
} catch {
|
|
383
|
+
// Connection failed, continue with next server
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const separator = icons.separator.repeat(40);
|
|
388
|
+
console.log('');
|
|
389
|
+
console.log(colors.primaryBright(`${icons.tool} MCP Servers`));
|
|
390
|
+
console.log(colors.border(separator));
|
|
391
|
+
console.log('');
|
|
392
|
+
|
|
393
|
+
serverNames.forEach((name) => {
|
|
394
|
+
const server = mcpManager.getServer(name);
|
|
395
|
+
const connected = server?.isServerConnected() ? icons.success : icons.error;
|
|
396
|
+
const status = server?.isServerConnected() ? colors.success(connected) : colors.error(connected);
|
|
397
|
+
const toolNames = server?.getToolNames().join(', ') || '';
|
|
398
|
+
|
|
399
|
+
console.log(` ${status} ${colors.primaryBright(name)}`);
|
|
400
|
+
console.log(` ${colors.textDim(`Tools: ${toolNames}`)}`);
|
|
401
|
+
console.log('');
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
process.exit(0);
|
|
405
|
+
} else if (options.get) {
|
|
406
|
+
const server = mcpManager.getServer(options.get);
|
|
407
|
+
|
|
408
|
+
if (!server) {
|
|
409
|
+
console.log('');
|
|
410
|
+
console.log(colors.error(`MCP server '${options.get}' not found`));
|
|
411
|
+
console.log(colors.textMuted('Use "xagent mcp --list" to see all configured servers'));
|
|
412
|
+
console.log('');
|
|
413
|
+
process.exit(1);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const config = (server as any).config;
|
|
417
|
+
const isConnected = server.isServerConnected();
|
|
418
|
+
const toolNames = server.getToolNames();
|
|
419
|
+
const tools = server.getTools();
|
|
420
|
+
|
|
421
|
+
console.log('');
|
|
422
|
+
console.log(colors.primaryBright(`${icons.tool} MCP Server: ${options.get}`));
|
|
423
|
+
console.log(colors.border(icons.separator.repeat(40)));
|
|
424
|
+
console.log('');
|
|
425
|
+
|
|
426
|
+
console.log(` ${colors.primaryBright('Status:')} ${isConnected ? colors.success('Connected') : colors.error('Disconnected')}`);
|
|
427
|
+
console.log(` ${colors.primaryBright('Transport:')} ${config.transport || 'stdio'}`);
|
|
428
|
+
|
|
429
|
+
if (config.url) {
|
|
430
|
+
console.log(` ${colors.primaryBright('URL:')} ${config.url}`);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (config.command) {
|
|
434
|
+
console.log(` ${colors.primaryBright('Command:')} ${config.command} ${(config.args || []).join(' ')}`);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (config.headers) {
|
|
438
|
+
console.log(` ${colors.primaryBright('Headers:')} ${JSON.stringify(config.headers)}`);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
console.log(` ${colors.primaryBright('Tools:')} ${toolNames.length > 0 ? toolNames.join(', ') : colors.textMuted('(none)')}`);
|
|
442
|
+
|
|
443
|
+
if (tools.length > 0) {
|
|
444
|
+
console.log('');
|
|
445
|
+
console.log(colors.textMuted(' Available tools:'));
|
|
446
|
+
tools.forEach((tool: any) => {
|
|
447
|
+
console.log(` - ${colors.primaryBright(tool.name)}`);
|
|
448
|
+
if (tool.description) {
|
|
449
|
+
console.log(` ${colors.textDim(tool.description.substring(0, 60))}${tool.description.length > 60 ? '...' : ''}`);
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
console.log('');
|
|
455
|
+
process.exit(0);
|
|
456
|
+
} else if (options.add !== undefined) {
|
|
457
|
+
// Check if running in non-interactive mode (transport and required params provided)
|
|
458
|
+
const hasTransport = options.transport;
|
|
459
|
+
const hasCommand = options.command;
|
|
460
|
+
const hasUrl = options.url;
|
|
461
|
+
const isNonInteractive = hasTransport && (hasCommand || hasUrl);
|
|
462
|
+
|
|
463
|
+
if (isNonInteractive) {
|
|
464
|
+
// Non-interactive mode: use command line arguments
|
|
465
|
+
const name = options.add || `mcp-${options.transport}-${Date.now().toString(36)}`;
|
|
466
|
+
const transport = options.transport;
|
|
467
|
+
|
|
468
|
+
const config: any = {
|
|
469
|
+
transport: transport,
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
if (transport === 'stdio') {
|
|
473
|
+
if (!options.command) {
|
|
474
|
+
console.log('');
|
|
475
|
+
console.log(colors.error('Error: --command is required for stdio transport'));
|
|
476
|
+
console.log('');
|
|
477
|
+
process.exit(1);
|
|
478
|
+
}
|
|
479
|
+
config.command = options.command;
|
|
480
|
+
if (options.args) {
|
|
481
|
+
config.args = options.args.split(',').map((a: string) => a.trim());
|
|
482
|
+
}
|
|
483
|
+
} else if (transport === 'http') {
|
|
484
|
+
if (!options.url) {
|
|
485
|
+
console.log('');
|
|
486
|
+
console.log(colors.error('Error: --url is required for http transport'));
|
|
487
|
+
console.log('');
|
|
488
|
+
process.exit(1);
|
|
489
|
+
}
|
|
490
|
+
config.url = options.url;
|
|
491
|
+
|
|
492
|
+
const headers: Record<string, string> = {};
|
|
493
|
+
|
|
494
|
+
if (options.token) {
|
|
495
|
+
headers['Authorization'] = `Bearer ${options.token}`;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (options.header) {
|
|
499
|
+
const headerArray = Array.isArray(options.header) ? options.header : [options.header];
|
|
500
|
+
for (const h of headerArray) {
|
|
501
|
+
const colonIndex = h.indexOf(':');
|
|
502
|
+
if (colonIndex > 0) {
|
|
503
|
+
const key = h.substring(0, colonIndex).trim();
|
|
504
|
+
const value = h.substring(colonIndex + 1).trim();
|
|
505
|
+
headers[key] = value;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (Object.keys(headers).length > 0) {
|
|
511
|
+
config.headers = headers;
|
|
512
|
+
}
|
|
513
|
+
} else {
|
|
514
|
+
console.log('');
|
|
515
|
+
console.log(colors.error(`Error: Unknown transport type: ${transport}`));
|
|
516
|
+
console.log(colors.textMuted('Valid types: stdio, http'));
|
|
517
|
+
console.log('');
|
|
518
|
+
process.exit(1);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Skip confirmation in non-interactive mode
|
|
522
|
+
if (!options.yes) {
|
|
523
|
+
console.log('');
|
|
524
|
+
console.log(colors.textMuted('Server configuration:'));
|
|
525
|
+
console.log(` ${colors.primaryBright('Name:')} ${name}`);
|
|
526
|
+
console.log(` ${colors.primaryBright('Transport:')} ${config.transport}`);
|
|
527
|
+
if (config.command) {
|
|
528
|
+
console.log(` ${colors.primaryBright('Command:')} ${config.command} ${(config.args || []).join(' ')}`);
|
|
529
|
+
}
|
|
530
|
+
if (config.url) {
|
|
531
|
+
console.log(` ${colors.primaryBright('URL:')} ${config.url}`);
|
|
532
|
+
if (config.authToken) {
|
|
533
|
+
console.log(` ${colors.primaryBright('Token:')} [hidden]`);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
console.log('');
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
try {
|
|
540
|
+
// Save to config
|
|
541
|
+
configManager.addMcpServer(name, config);
|
|
542
|
+
configManager.save(options.scope);
|
|
543
|
+
|
|
544
|
+
// Register with MCP manager
|
|
545
|
+
mcpManager.registerServer(name, config);
|
|
546
|
+
|
|
547
|
+
// Try to connect
|
|
548
|
+
let connected = false;
|
|
549
|
+
try {
|
|
550
|
+
await mcpManager.connectServer(name);
|
|
551
|
+
connected = true;
|
|
552
|
+
} catch (error: any) {
|
|
553
|
+
console.log(colors.textMuted(` ⚠️ Connection failed: ${error.message}`));
|
|
554
|
+
console.log(colors.textMuted(' The server is saved but not connected.'));
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
if (connected) {
|
|
558
|
+
console.log('');
|
|
559
|
+
console.log(colors.success(`✅ MCP server '${name}' added and connected successfully`));
|
|
560
|
+
} else {
|
|
561
|
+
console.log('');
|
|
562
|
+
console.log(colors.success(`✅ MCP server '${name}' added successfully`));
|
|
563
|
+
}
|
|
564
|
+
console.log('');
|
|
565
|
+
process.exit(0);
|
|
566
|
+
} catch (error: any) {
|
|
567
|
+
console.log('');
|
|
568
|
+
console.log(colors.error(`Failed to add MCP server: ${error.message}`));
|
|
569
|
+
console.log('');
|
|
570
|
+
process.exit(1);
|
|
571
|
+
}
|
|
572
|
+
} else {
|
|
573
|
+
// Interactive mode
|
|
574
|
+
const { text, select, confirm } = await import('@clack/prompts');
|
|
575
|
+
|
|
576
|
+
const separator = icons.separator.repeat(40);
|
|
577
|
+
console.log('');
|
|
578
|
+
console.log(colors.primaryBright(`${icons.tool} Add MCP Server`));
|
|
579
|
+
console.log(colors.border(separator));
|
|
580
|
+
console.log('');
|
|
581
|
+
|
|
582
|
+
// Step 1: Enter server name
|
|
583
|
+
let name = options.add;
|
|
584
|
+
if (!name) {
|
|
585
|
+
name = await text({
|
|
586
|
+
message: 'Enter MCP server name:',
|
|
587
|
+
validate: (value: string | undefined) => {
|
|
588
|
+
if (!value || !value.trim()) {
|
|
589
|
+
return 'Server name is required';
|
|
590
|
+
}
|
|
591
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(value)) {
|
|
592
|
+
return 'Server name must contain only alphanumeric characters, hyphens, and underscores';
|
|
593
|
+
}
|
|
594
|
+
return undefined;
|
|
595
|
+
},
|
|
596
|
+
}) as string;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// Step 2: Select transport type
|
|
600
|
+
const transport = await select({
|
|
601
|
+
message: 'Select transport type:',
|
|
602
|
+
options: [
|
|
603
|
+
{ value: 'stdio', label: 'Stdio (stdin/stdout)' },
|
|
604
|
+
{ value: 'http', label: 'HTTP (Streamable HTTP)' },
|
|
605
|
+
],
|
|
606
|
+
}) as string | symbol;
|
|
607
|
+
|
|
608
|
+
if (typeof transport === 'symbol') {
|
|
609
|
+
console.log('');
|
|
610
|
+
console.log(colors.textMuted('Cancelled'));
|
|
611
|
+
console.log('');
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const config: any = {
|
|
616
|
+
transport: transport as 'stdio' | 'http',
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
if (transport === 'stdio') {
|
|
620
|
+
// Step 3: Enter command
|
|
621
|
+
config.command = await text({
|
|
622
|
+
message: 'Enter command (for stdio transport):',
|
|
623
|
+
validate: (value: string | undefined) =>
|
|
624
|
+
value && value.trim() ? undefined : 'Command is required',
|
|
625
|
+
}) as string;
|
|
626
|
+
|
|
627
|
+
// Step 4: Enter arguments
|
|
628
|
+
const argsInput = await text({
|
|
629
|
+
message: 'Enter arguments (comma-separated, for stdio transport):',
|
|
630
|
+
defaultValue: '',
|
|
631
|
+
}) as string;
|
|
632
|
+
|
|
633
|
+
if (argsInput.trim()) {
|
|
634
|
+
config.args = argsInput.split(',').map((a: string) => a.trim());
|
|
635
|
+
}
|
|
636
|
+
} else {
|
|
637
|
+
// Step 3: Enter URL
|
|
638
|
+
let url = '';
|
|
639
|
+
while (!url) {
|
|
640
|
+
url = await text({
|
|
641
|
+
message: 'Enter server URL (for HTTP transport):',
|
|
642
|
+
validate: (value: string | undefined) => {
|
|
643
|
+
if (!value || !value.trim()) {
|
|
644
|
+
return 'URL is required';
|
|
645
|
+
}
|
|
646
|
+
try {
|
|
647
|
+
new URL(value);
|
|
648
|
+
return undefined;
|
|
649
|
+
} catch {
|
|
650
|
+
return 'Invalid URL format (e.g., https://example.com)';
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
}) as string;
|
|
654
|
+
}
|
|
655
|
+
config.url = url;
|
|
656
|
+
|
|
657
|
+
const headers: Record<string, string> = {};
|
|
658
|
+
|
|
659
|
+
// Step 4: Enter auth token (optional)
|
|
660
|
+
const authToken = await text({
|
|
661
|
+
message: 'Enter Bearer token (optional):',
|
|
662
|
+
defaultValue: '',
|
|
663
|
+
}) as string;
|
|
664
|
+
|
|
665
|
+
if (authToken.trim()) {
|
|
666
|
+
headers['Authorization'] = `Bearer ${authToken}`;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// Step 5: Enter custom headers (optional)
|
|
670
|
+
const headersInput = await text({
|
|
671
|
+
message: 'Enter custom headers as JSON (optional):',
|
|
672
|
+
defaultValue: '',
|
|
673
|
+
}) as string;
|
|
674
|
+
|
|
675
|
+
if (headersInput.trim()) {
|
|
676
|
+
try {
|
|
677
|
+
const customHeaders = JSON.parse(headersInput);
|
|
678
|
+
Object.assign(headers, customHeaders);
|
|
679
|
+
} catch {
|
|
680
|
+
// Ignore invalid JSON
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
if (Object.keys(headers).length > 0) {
|
|
685
|
+
config.headers = headers;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// Step 6: Confirm and save
|
|
690
|
+
console.log('');
|
|
691
|
+
console.log(colors.textMuted('Server configuration:'));
|
|
692
|
+
console.log(` ${colors.primaryBright('Name:')} ${name}`);
|
|
693
|
+
console.log(` ${colors.primaryBright('Transport:')} ${config.transport}`);
|
|
694
|
+
if (config.command) {
|
|
695
|
+
console.log(` ${colors.primaryBright('Command:')} ${config.command} ${(config.args || []).join(' ')}`);
|
|
696
|
+
}
|
|
697
|
+
if (config.url) {
|
|
698
|
+
console.log(` ${colors.primaryBright('URL:')} ${config.url}`);
|
|
699
|
+
}
|
|
700
|
+
console.log('');
|
|
701
|
+
|
|
702
|
+
const shouldSave = await confirm({
|
|
703
|
+
message: 'Save this MCP server configuration?',
|
|
704
|
+
}) as boolean | symbol;
|
|
705
|
+
|
|
706
|
+
if (typeof shouldSave === 'symbol' || !shouldSave) {
|
|
707
|
+
console.log('');
|
|
708
|
+
console.log(colors.textMuted('Cancelled'));
|
|
709
|
+
console.log('');
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
try {
|
|
714
|
+
// Save to config
|
|
715
|
+
configManager.addMcpServer(name, config);
|
|
716
|
+
configManager.save(options.scope);
|
|
717
|
+
|
|
718
|
+
// Register with MCP manager
|
|
719
|
+
mcpManager.registerServer(name, config);
|
|
720
|
+
|
|
721
|
+
// Try to connect
|
|
722
|
+
let connected = false;
|
|
723
|
+
try {
|
|
724
|
+
await mcpManager.connectServer(name);
|
|
725
|
+
connected = true;
|
|
726
|
+
} catch (error: any) {
|
|
727
|
+
console.log(colors.textMuted(` ⚠️ Connection failed: ${error.message}`));
|
|
728
|
+
console.log(colors.textMuted(' The server is saved but not connected. Use "/mcp refresh" in interactive mode to retry.'));
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
if (connected) {
|
|
732
|
+
console.log('');
|
|
733
|
+
console.log(colors.success(`✅ MCP server '${name}' added and connected successfully`));
|
|
734
|
+
} else {
|
|
735
|
+
console.log('');
|
|
736
|
+
console.log(colors.success(`✅ MCP server '${name}' added successfully (not connected)`));
|
|
737
|
+
}
|
|
738
|
+
console.log('');
|
|
739
|
+
} catch (error: any) {
|
|
740
|
+
console.log('');
|
|
741
|
+
console.log(colors.error(`Failed to add MCP server: ${error.message}`));
|
|
742
|
+
console.log('');
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
} else if (options.remove) {
|
|
746
|
+
try {
|
|
747
|
+
mcpManager.disconnectServer(options.remove);
|
|
748
|
+
const mcpServers = configManager.getMcpServers();
|
|
749
|
+
delete mcpServers[options.remove];
|
|
750
|
+
configManager.save(options.scope);
|
|
751
|
+
console.log('');
|
|
752
|
+
console.log(colors.success(`MCP server ${options.remove} removed successfully`));
|
|
753
|
+
console.log('');
|
|
754
|
+
process.exit(0);
|
|
755
|
+
} catch (error: any) {
|
|
756
|
+
const { message, suggestion } = formatError(error);
|
|
757
|
+
console.log('');
|
|
758
|
+
console.log(colors.error(`Failed to remove MCP server: ${message}`));
|
|
759
|
+
console.log(colors.textMuted(suggestion));
|
|
760
|
+
console.log('');
|
|
761
|
+
process.exit(1);
|
|
762
|
+
}
|
|
763
|
+
} else {
|
|
764
|
+
console.log('');
|
|
765
|
+
console.log(colors.warning('Please specify an action: --list, --get, --add, or --remove'));
|
|
766
|
+
console.log('');
|
|
767
|
+
console.log(colors.textMuted('Usage:'));
|
|
768
|
+
console.log(` ${colors.primaryBright('xagent mcp --list')} ${colors.textMuted('| List all MCP servers')}`);
|
|
769
|
+
console.log(` ${colors.primaryBright('xagent mcp --get <name>')} ${colors.textMuted('| Get MCP server details')}`);
|
|
770
|
+
console.log(` ${colors.primaryBright('xagent mcp --add')} ${colors.textMuted('| Add MCP server (interactive)')}`);
|
|
771
|
+
console.log('');
|
|
772
|
+
console.log(colors.textMuted('Non-interactive examples:'));
|
|
773
|
+
console.log(` ${colors.primaryBright('xagent mcp --add -t stdio -c "npx" --args "-y,@modelcontextprotocol/server-github"')}`);
|
|
774
|
+
console.log(` ${colors.primaryBright('xagent mcp --add -t http -u "https://example.com/mcp" -k "token"')}`);
|
|
775
|
+
console.log('');
|
|
776
|
+
console.log(colors.textMuted('Options:'));
|
|
777
|
+
console.log(` ${colors.primaryBright('-t, --transport')} ${colors.textMuted('Transport: stdio or http')}`);
|
|
778
|
+
console.log(` ${colors.primaryBright('-c, --command')} ${colors.textMuted('Command for stdio transport')}`);
|
|
779
|
+
console.log(` ${colors.primaryBright('--args')} ${colors.textMuted('Arguments (comma-separated)')}`);
|
|
780
|
+
console.log(` ${colors.primaryBright('-u, --url')} ${colors.textMuted('URL for HTTP transport')}`);
|
|
781
|
+
console.log(` ${colors.primaryBright('-k, --token')} ${colors.textMuted('Bearer authentication token')}`);
|
|
782
|
+
console.log(` ${colors.primaryBright('--header')} ${colors.textMuted('Custom header (key:value)')}`);
|
|
783
|
+
console.log(` ${colors.primaryBright('-y, --yes')} ${colors.textMuted('Skip confirmation')}`);
|
|
784
|
+
console.log('');
|
|
785
|
+
process.exit(1);
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
program
|
|
790
|
+
.command('init')
|
|
791
|
+
.description('Initialize XAGENT.md for the current project')
|
|
792
|
+
.action(async () => {
|
|
793
|
+
const { getMemoryManager } = await import('./memory.js');
|
|
794
|
+
const memoryManager = getMemoryManager(process.cwd());
|
|
795
|
+
|
|
796
|
+
const separator = icons.separator.repeat(40);
|
|
797
|
+
console.log('');
|
|
798
|
+
console.log(colors.primaryBright(`${icons.folder} Initializing Project Context`));
|
|
799
|
+
console.log(colors.border(separator));
|
|
800
|
+
console.log('');
|
|
801
|
+
|
|
802
|
+
try {
|
|
803
|
+
await memoryManager.initializeProject(process.cwd());
|
|
804
|
+
console.log(colors.success('Project initialized successfully!'));
|
|
805
|
+
console.log(colors.textMuted('You can now run "xagent start" to begin'));
|
|
806
|
+
console.log('');
|
|
807
|
+
process.exit(0);
|
|
808
|
+
} catch (error: any) {
|
|
809
|
+
const { message, suggestion } = formatError(error);
|
|
810
|
+
console.log(colors.error(`Initialization failed: ${message}`));
|
|
811
|
+
console.log(colors.textMuted(suggestion));
|
|
812
|
+
console.log('');
|
|
813
|
+
process.exit(1);
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
program
|
|
818
|
+
.command('workflow')
|
|
819
|
+
.description('Add, list, or remove workflows')
|
|
820
|
+
.option('--add <workflow-id>', 'Add a workflow from the marketplace')
|
|
821
|
+
.option('-l, --list', 'List all installed workflows')
|
|
822
|
+
.option('-r, --remove <workflow-id>', 'Remove a workflow')
|
|
823
|
+
.option('--scope <scope>', 'Scope (global or project)', 'project')
|
|
824
|
+
.action(async (options) => {
|
|
825
|
+
const { getWorkflowManager } = await import('./workflow.js');
|
|
826
|
+
const workflowManager = getWorkflowManager(process.cwd());
|
|
827
|
+
|
|
828
|
+
if (options.list) {
|
|
829
|
+
const workflows = workflowManager.listWorkflows();
|
|
830
|
+
|
|
831
|
+
if (workflows.length === 0) {
|
|
832
|
+
console.log('');
|
|
833
|
+
console.log(colors.warning('No workflows installed'));
|
|
834
|
+
console.log(colors.textMuted('Use --add to install workflows from the marketplace'));
|
|
835
|
+
console.log('');
|
|
836
|
+
process.exit(0);
|
|
837
|
+
} else {
|
|
838
|
+
const separator = icons.separator.repeat(40);
|
|
839
|
+
console.log('');
|
|
840
|
+
console.log(colors.primaryBright(`${icons.rocket} Installed Workflows`));
|
|
841
|
+
console.log(colors.border(separator));
|
|
842
|
+
console.log('');
|
|
843
|
+
|
|
844
|
+
workflows.forEach((workflow, index) => {
|
|
845
|
+
console.log(` ${colors.primaryBright(`${index + 1}. ${workflow.name}`)}`);
|
|
846
|
+
console.log(` ${colors.textDim(` ID: ${workflow.id}`)}`);
|
|
847
|
+
console.log(` ${colors.textDim(` ${workflow.description}`)}`);
|
|
848
|
+
console.log('');
|
|
849
|
+
});
|
|
850
|
+
process.exit(0);
|
|
851
|
+
}
|
|
852
|
+
} else if (options.add) {
|
|
853
|
+
try {
|
|
854
|
+
await workflowManager.addWorkflow(options.add, options.scope);
|
|
855
|
+
console.log('');
|
|
856
|
+
console.log(colors.success(`Workflow ${options.add} added successfully!`));
|
|
857
|
+
console.log('');
|
|
858
|
+
process.exit(0);
|
|
859
|
+
} catch (error: any) {
|
|
860
|
+
const { message, suggestion } = formatError(error);
|
|
861
|
+
console.log('');
|
|
862
|
+
console.log(colors.error(message));
|
|
863
|
+
console.log(colors.textMuted(suggestion));
|
|
864
|
+
console.log('');
|
|
865
|
+
process.exit(1);
|
|
866
|
+
}
|
|
867
|
+
} else if (options.remove) {
|
|
868
|
+
try {
|
|
869
|
+
await workflowManager.removeWorkflow(options.remove, options.scope);
|
|
870
|
+
console.log('');
|
|
871
|
+
console.log(colors.success(`Workflow ${options.remove} removed successfully!`));
|
|
872
|
+
console.log('');
|
|
873
|
+
process.exit(0);
|
|
874
|
+
} catch (error: any) {
|
|
875
|
+
const { message, suggestion } = formatError(error);
|
|
876
|
+
console.log('');
|
|
877
|
+
console.log(colors.error(message));
|
|
878
|
+
console.log(colors.textMuted(suggestion));
|
|
879
|
+
console.log('');
|
|
880
|
+
process.exit(1);
|
|
881
|
+
}
|
|
882
|
+
} else {
|
|
883
|
+
console.log('');
|
|
884
|
+
console.log(colors.warning('Please specify an action: --list, --add, or --remove'));
|
|
885
|
+
console.log('');
|
|
886
|
+
process.exit(1);
|
|
887
|
+
}
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
program
|
|
891
|
+
.command('skill')
|
|
892
|
+
.description('Manage skills')
|
|
893
|
+
.option('-l, --list', 'List all installed user skills')
|
|
894
|
+
.option('--add <source>', 'Install a skill (auto-detects local path or remote URL)')
|
|
895
|
+
.option('-r, --remove <skill-id>', 'Remove a user-installed skill')
|
|
896
|
+
.action(async (options) => {
|
|
897
|
+
const { getConfigManager } = await import('./config.js');
|
|
898
|
+
const configManager = getConfigManager();
|
|
899
|
+
const { promises: fs } = await import('fs');
|
|
900
|
+
const pathModule = await import('path');
|
|
901
|
+
const { exec } = await import('child_process');
|
|
902
|
+
const { promisify } = await import('util');
|
|
903
|
+
const os = await import('os');
|
|
904
|
+
|
|
905
|
+
const _execAsync = promisify(exec);
|
|
906
|
+
const userSkillsPath = configManager.getUserSkillsPath() || pathModule.join(os.homedir(), '.xagent', 'skills');
|
|
907
|
+
const _userNodeModulesPath = configManager.getUserNodeModulesPath() || pathModule.join(os.homedir(), '.xagent', 'node_modules');
|
|
908
|
+
|
|
909
|
+
if (options.add) {
|
|
910
|
+
const separator = icons.separator.repeat(40);
|
|
911
|
+
console.log('');
|
|
912
|
+
console.log(colors.primaryBright(`${icons.tool} Install Skill`));
|
|
913
|
+
console.log(colors.border(separator));
|
|
914
|
+
console.log('');
|
|
915
|
+
|
|
916
|
+
const source = options.add.trim();
|
|
917
|
+
const { installSkill } = await import('./skill-installer.js');
|
|
918
|
+
const { parseSource } = await import('./skill-installer.js');
|
|
919
|
+
|
|
920
|
+
// Auto-detect if source is local or remote
|
|
921
|
+
const parsed = parseSource(source);
|
|
922
|
+
const isLocal = parsed.type === 'local';
|
|
923
|
+
|
|
924
|
+
if (isLocal) {
|
|
925
|
+
// Local installation
|
|
926
|
+
const sourcePath = pathModule.resolve(source);
|
|
927
|
+
const skillName = pathModule.basename(sourcePath);
|
|
928
|
+
const destPath = pathModule.join(userSkillsPath, skillName);
|
|
929
|
+
|
|
930
|
+
try {
|
|
931
|
+
// Check if source exists
|
|
932
|
+
await fs.access(sourcePath);
|
|
933
|
+
|
|
934
|
+
// Check if SKILL.md exists
|
|
935
|
+
const skillMdPath = pathModule.join(sourcePath, 'SKILL.md');
|
|
936
|
+
try {
|
|
937
|
+
await fs.access(skillMdPath);
|
|
938
|
+
} catch {
|
|
939
|
+
console.log(colors.error(`SKILL.md not found in ${sourcePath}`));
|
|
940
|
+
console.log(colors.textMuted('Each skill must have a SKILL.md file'));
|
|
941
|
+
console.log('');
|
|
942
|
+
process.exit(1);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// Check if skill already exists in user skills path
|
|
946
|
+
try {
|
|
947
|
+
await fs.access(destPath);
|
|
948
|
+
console.log(colors.warning(`Skill "${skillName}" already installed`));
|
|
949
|
+
console.log(colors.textMuted(`Use "xagent skill -r ${skillName}" to remove it first`));
|
|
950
|
+
console.log('');
|
|
951
|
+
process.exit(1);
|
|
952
|
+
} catch {
|
|
953
|
+
// Doesn't exist, proceed
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
// Ensure user skills directory exists
|
|
957
|
+
await fs.mkdir(userSkillsPath, { recursive: true });
|
|
958
|
+
|
|
959
|
+
// Copy the skill
|
|
960
|
+
await copyDirectory(sourcePath, destPath);
|
|
961
|
+
console.log('');
|
|
962
|
+
console.log(colors.success(`✅ Skill "${skillName}" installed successfully`));
|
|
963
|
+
console.log(colors.textMuted(` Location: ${destPath}`));
|
|
964
|
+
console.log(colors.textMuted(` Type: Local`));
|
|
965
|
+
console.log('');
|
|
966
|
+
|
|
967
|
+
// Notify running xAgent to update system prompt
|
|
968
|
+
await notifySkillUpdate(userSkillsPath);
|
|
969
|
+
console.log('');
|
|
970
|
+
process.exit(0);
|
|
971
|
+
} catch (error: any) {
|
|
972
|
+
const { message, suggestion } = formatError(error);
|
|
973
|
+
console.log(colors.error(`Failed to install skill: ${message}`));
|
|
974
|
+
console.log(colors.textMuted(suggestion));
|
|
975
|
+
console.log('');
|
|
976
|
+
process.exit(1);
|
|
977
|
+
}
|
|
978
|
+
} else {
|
|
979
|
+
// Remote installation
|
|
980
|
+
console.log(colors.textMuted(` Source: ${source}`));
|
|
981
|
+
console.log(colors.textMuted(` Type: Remote`));
|
|
982
|
+
console.log('');
|
|
983
|
+
|
|
984
|
+
try {
|
|
985
|
+
const result = await installSkill(source);
|
|
986
|
+
|
|
987
|
+
if (result.success) {
|
|
988
|
+
console.log(colors.success(`✅ Skill "${result.skillName}" installed successfully`));
|
|
989
|
+
console.log(colors.textMuted(` Location: ${result.skillPath}`));
|
|
990
|
+
console.log('');
|
|
991
|
+
|
|
992
|
+
// Notify running xAgent to update system prompt
|
|
993
|
+
await notifySkillUpdate(userSkillsPath);
|
|
994
|
+
console.log(colors.textMuted('Note: Run "xagent start" to use the new skill'));
|
|
995
|
+
console.log('');
|
|
996
|
+
process.exit(0);
|
|
997
|
+
} else {
|
|
998
|
+
console.log(colors.error(`Failed to install skill: ${result.error}`));
|
|
999
|
+
console.log('');
|
|
1000
|
+
process.exit(1);
|
|
1001
|
+
}
|
|
1002
|
+
} catch (error: any) {
|
|
1003
|
+
const { message, suggestion } = formatError(error);
|
|
1004
|
+
console.log(colors.error(`Failed to install skill: ${message}`));
|
|
1005
|
+
console.log(colors.textMuted(suggestion));
|
|
1006
|
+
console.log('');
|
|
1007
|
+
process.exit(1);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
} else if (options.list) {
|
|
1011
|
+
const separator = icons.separator.repeat(40);
|
|
1012
|
+
console.log('');
|
|
1013
|
+
console.log(colors.primaryBright(`${icons.tool} Skills`));
|
|
1014
|
+
console.log(colors.border(separator));
|
|
1015
|
+
console.log('');
|
|
1016
|
+
|
|
1017
|
+
try {
|
|
1018
|
+
const entries = await fs.readdir(userSkillsPath, { withFileTypes: true });
|
|
1019
|
+
const skills = entries.filter(e => e.isDirectory());
|
|
1020
|
+
|
|
1021
|
+
if (skills.length === 0) {
|
|
1022
|
+
console.log(colors.textMuted('No user skills installed'));
|
|
1023
|
+
console.log('');
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
for (const skill of skills) {
|
|
1028
|
+
const skillPath = path.join(userSkillsPath, skill.name);
|
|
1029
|
+
const skillMdPath = path.join(skillPath, 'SKILL.md');
|
|
1030
|
+
|
|
1031
|
+
try {
|
|
1032
|
+
const content = await fs.readFile(skillMdPath, 'utf-8');
|
|
1033
|
+
// Simple parsing for name and description
|
|
1034
|
+
const nameMatch = content.match(/^name:\s*(.+)$/m);
|
|
1035
|
+
const descMatch = content.match(/^description:\s*(.+)$/m);
|
|
1036
|
+
const name = nameMatch ? nameMatch[1].trim() : skill.name;
|
|
1037
|
+
const description = descMatch ? descMatch[1].trim() : 'No description';
|
|
1038
|
+
|
|
1039
|
+
console.log(` ${colors.primaryBright(`• ${name}`)}`);
|
|
1040
|
+
console.log(` ${colors.textDim(` ${description}`)}`);
|
|
1041
|
+
console.log('');
|
|
1042
|
+
} catch {
|
|
1043
|
+
console.log(` ${colors.primaryBright(`• ${skill.name}`)}`);
|
|
1044
|
+
console.log(` ${colors.textDim(` (Missing SKILL.md)`)}`);
|
|
1045
|
+
console.log('');
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
console.log(colors.textMuted(`Skills directory: ${userSkillsPath}`));
|
|
1050
|
+
console.log('');
|
|
1051
|
+
process.exit(0);
|
|
1052
|
+
} catch {
|
|
1053
|
+
console.log(colors.textMuted('No user skills installed'));
|
|
1054
|
+
console.log('');
|
|
1055
|
+
}
|
|
1056
|
+
} else if (options.remove) {
|
|
1057
|
+
const skillPath = path.join(userSkillsPath, options.remove);
|
|
1058
|
+
|
|
1059
|
+
// Protect find-skills from deletion
|
|
1060
|
+
if (options.remove === 'find-skills') {
|
|
1061
|
+
console.log('');
|
|
1062
|
+
console.log(colors.error(`Cannot remove protected skill: find-skills`));
|
|
1063
|
+
console.log(colors.textMuted('find-skills is a built-in skill that helps you discover and install other skills.'));
|
|
1064
|
+
console.log('');
|
|
1065
|
+
process.exit(1);
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
try {
|
|
1069
|
+
await fs.access(skillPath);
|
|
1070
|
+
// Verify it's in user skills path (not built-in)
|
|
1071
|
+
if (!skillPath.startsWith(userSkillsPath)) {
|
|
1072
|
+
console.log('');
|
|
1073
|
+
console.log(colors.error(`Cannot remove skill outside user directory: ${options.remove}`));
|
|
1074
|
+
console.log('');
|
|
1075
|
+
process.exit(1);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
// Remove the skill directory
|
|
1079
|
+
await fs.rm(skillPath, { recursive: true, force: true });
|
|
1080
|
+
console.log('');
|
|
1081
|
+
console.log(colors.success(`✅ Skill ${options.remove} removed successfully`));
|
|
1082
|
+
console.log('');
|
|
1083
|
+
|
|
1084
|
+
// Notify running xAgent to update system prompt
|
|
1085
|
+
await notifySkillUpdate(userSkillsPath);
|
|
1086
|
+
console.log('');
|
|
1087
|
+
process.exit(0);
|
|
1088
|
+
} catch {
|
|
1089
|
+
console.log('');
|
|
1090
|
+
console.log(colors.error(`Skill not found: ${options.remove}`));
|
|
1091
|
+
console.log('');
|
|
1092
|
+
process.exit(1);
|
|
1093
|
+
}
|
|
1094
|
+
} else {
|
|
1095
|
+
// Show help
|
|
1096
|
+
console.log('');
|
|
1097
|
+
console.log(colors.textMuted('Usage:'));
|
|
1098
|
+
console.log(` ${colors.primaryBright('xagent skill -l')} ${colors.textDim('| List all skills')}`);
|
|
1099
|
+
console.log(` ${colors.primaryBright('xagent skill --add <source>')} ${colors.textDim('| Install skill (auto-detects local or remote)')}`);
|
|
1100
|
+
console.log(` ${colors.primaryBright('xagent skill -r <name>')} ${colors.textDim('| Remove a skill')}`);
|
|
1101
|
+
console.log('');
|
|
1102
|
+
console.log(colors.textMuted('Examples:'));
|
|
1103
|
+
console.log(` ${colors.primaryBright('xagent skill --add ./my-skill')} ${colors.textDim('| Install from local path')}`);
|
|
1104
|
+
console.log(` ${colors.primaryBright('xagent skill --add owner/repo')} ${colors.textDim('| Install from GitHub')}`);
|
|
1105
|
+
console.log(` ${colors.primaryBright('xagent skill --add https://github.com/owner/repo')}`);
|
|
1106
|
+
console.log(` ${colors.primaryBright('xagent skill --add https://docs.example.com/skill.md')}`);
|
|
1107
|
+
console.log('');
|
|
1108
|
+
console.log(colors.textMuted('To install a new skill, use the interactive command:'));
|
|
1109
|
+
console.log(` ${colors.primaryBright('/skill add')}`);
|
|
1110
|
+
console.log('');
|
|
1111
|
+
process.exit(0);
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
program
|
|
1116
|
+
.command('version')
|
|
1117
|
+
.description('Display version and check for updates')
|
|
1118
|
+
.action(async () => {
|
|
1119
|
+
const separator = icons.separator.repeat(40);
|
|
1120
|
+
|
|
1121
|
+
console.log('');
|
|
1122
|
+
console.log(colors.gradient('╔════════════════════════════════════════════════════════════╗'));
|
|
1123
|
+
console.log(colors.gradient('║') + ' '.repeat(56) + colors.gradient('║'));
|
|
1124
|
+
console.log(' '.repeat(20) + colors.gradient('xAgent CLI') + ' '.repeat(29) + colors.gradient('║'));
|
|
1125
|
+
console.log(colors.gradient('║') + ' '.repeat(56) + colors.gradient('║'));
|
|
1126
|
+
console.log(colors.gradient('╚════════════════════════════════════════════════════════════╝'));
|
|
1127
|
+
console.log('');
|
|
1128
|
+
console.log(colors.border(separator));
|
|
1129
|
+
console.log('');
|
|
1130
|
+
console.log(` ${icons.info} ${colors.textMuted('Version:')} ${colors.primaryBright(packageJson.version)}`);
|
|
1131
|
+
console.log(` ${icons.code} ${colors.textMuted('Node.js:')} ${colors.textMuted(process.version)}`);
|
|
1132
|
+
console.log(` ${icons.bolt} ${colors.textMuted('Platform:')} ${colors.textMuted(process.platform + ' ' + process.arch)}`);
|
|
1133
|
+
console.log('');
|
|
1134
|
+
console.log(colors.border(separator));
|
|
1135
|
+
console.log('');
|
|
1136
|
+
console.log(` ${colors.primaryBright('📚 Documentation:')} ${colors.primaryBright('https://platform.xagent.cn/cli/')}`);
|
|
1137
|
+
console.log(` ${colors.primaryBright('💻 GitHub:')} ${colors.primaryBright('https://github.com/xagent-ai/xagent-cli')}`);
|
|
1138
|
+
console.log('');
|
|
1139
|
+
process.exit(0);
|
|
1140
|
+
});
|
|
1141
|
+
|
|
1142
|
+
program
|
|
1143
|
+
.command('gui')
|
|
1144
|
+
.description('Start GUI subagent for computer automation')
|
|
1145
|
+
.option('--headless', 'Run in headless mode (no visible window)', false)
|
|
1146
|
+
.action(async (options) => {
|
|
1147
|
+
const separator = icons.separator.repeat(40);
|
|
1148
|
+
console.log('');
|
|
1149
|
+
console.log(colors.primaryBright(`${icons.robot} GUI Subagent - Computer Automation`));
|
|
1150
|
+
console.log(colors.border(separator));
|
|
1151
|
+
console.log('');
|
|
1152
|
+
|
|
1153
|
+
try {
|
|
1154
|
+
const configManager = getConfigManager();
|
|
1155
|
+
const authConfig = configManager.getAuthConfig();
|
|
1156
|
+
|
|
1157
|
+
// Get GUI-specific VLM configuration
|
|
1158
|
+
const baseUrl = configManager.get('guiSubagentBaseUrl') || configManager.get('baseUrl') || '';
|
|
1159
|
+
const apiKey = configManager.get('guiSubagentApiKey') || configManager.get('apiKey') || '';
|
|
1160
|
+
const modelName = configManager.get('guiSubagentModel') || configManager.get('modelName') || '';
|
|
1161
|
+
|
|
1162
|
+
// Determine mode: local (openai_compatible) or remote
|
|
1163
|
+
const isLocalMode = authConfig.type === 'openai_compatible';
|
|
1164
|
+
|
|
1165
|
+
if (isLocalMode) {
|
|
1166
|
+
// Local mode: require baseUrl configuration
|
|
1167
|
+
if (!baseUrl) {
|
|
1168
|
+
console.log(colors.error('No VLM API URL configured for GUI subagent.'));
|
|
1169
|
+
console.log(colors.textMuted('Please run "xagent auth" and configure guiSubagentBaseUrl.'));
|
|
1170
|
+
console.log('');
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
console.log(colors.info(`${icons.brain} Using local VLM configuration`));
|
|
1174
|
+
console.log(colors.textMuted(` Model: ${modelName}`));
|
|
1175
|
+
console.log(colors.textMuted(` Base URL: ${baseUrl}`));
|
|
1176
|
+
console.log('');
|
|
1177
|
+
} else {
|
|
1178
|
+
// Remote mode
|
|
1179
|
+
console.log(colors.info(`${icons.brain} Using remote VLM service`));
|
|
1180
|
+
console.log(colors.textMuted(` Auth Type: ${authConfig.type}`));
|
|
1181
|
+
console.log('');
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
const { createGUISubAgent } = await import('./gui-subagent/index.js');
|
|
1185
|
+
|
|
1186
|
+
// Create ref for tracking first VLM call across loop iterations
|
|
1187
|
+
const isFirstVlmCallRef = { current: true };
|
|
1188
|
+
|
|
1189
|
+
// Create remoteVlmCaller for remote mode (uses full messages for consistent behavior)
|
|
1190
|
+
let remoteVlmCaller: ((messages: any[], systemPrompt: string, taskId: string, isFirstVlmCallRef: { current: boolean }) => Promise<string>) | undefined;
|
|
1191
|
+
|
|
1192
|
+
if (!isLocalMode && authConfig.baseUrl) {
|
|
1193
|
+
const remoteBaseUrl = `${authConfig.baseUrl}/api/agent/vlm`;
|
|
1194
|
+
remoteVlmCaller = async (messages: any[], _systemPrompt: string, _taskId: string, isFirstVlmCallRef: { current: boolean }): Promise<string> => {
|
|
1195
|
+
const status = isFirstVlmCallRef.current ? 'begin' : 'continue';
|
|
1196
|
+
const response = await fetch(remoteBaseUrl, {
|
|
1197
|
+
method: 'POST',
|
|
1198
|
+
headers: {
|
|
1199
|
+
'Content-Type': 'application/json',
|
|
1200
|
+
'Authorization': `Bearer ${authConfig.apiKey || ''}`,
|
|
1201
|
+
},
|
|
1202
|
+
body: JSON.stringify({
|
|
1203
|
+
messages,
|
|
1204
|
+
taskId: _taskId,
|
|
1205
|
+
status
|
|
1206
|
+
}),
|
|
1207
|
+
});
|
|
1208
|
+
if (!response.ok) {
|
|
1209
|
+
const errorText = await response.text();
|
|
1210
|
+
throw new Error(`Remote VLM error: ${response.status} - ${errorText}`);
|
|
1211
|
+
}
|
|
1212
|
+
const result = await response.json() as { response?: string; content?: string; message?: string };
|
|
1213
|
+
// Update ref after call so subsequent calls use 'continue'
|
|
1214
|
+
isFirstVlmCallRef.current = false;
|
|
1215
|
+
return result.response || result.content || result.message || '';
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
const _guiAgent = await createGUISubAgent({
|
|
1220
|
+
headless: options.headless ?? false,
|
|
1221
|
+
model: isLocalMode ? modelName : undefined,
|
|
1222
|
+
modelBaseUrl: isLocalMode ? baseUrl : undefined,
|
|
1223
|
+
modelApiKey: isLocalMode ? apiKey : undefined,
|
|
1224
|
+
isFirstVlmCallRef,
|
|
1225
|
+
remoteVlmCaller,
|
|
1226
|
+
isLocalMode,
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
console.log(colors.success('✅ GUI Subagent initialized successfully!'));
|
|
1230
|
+
console.log('');
|
|
1231
|
+
console.log(colors.textMuted('Available actions:'));
|
|
1232
|
+
console.log(colors.textDim(' - click: Click on an element'));
|
|
1233
|
+
console.log(colors.textDim(' - double_click: Double click'));
|
|
1234
|
+
console.log(colors.textDim(' - right_click: Right click'));
|
|
1235
|
+
console.log(colors.textDim(' - drag: Drag from one position to another'));
|
|
1236
|
+
console.log(colors.textDim(' - type: Type text'));
|
|
1237
|
+
console.log(colors.textDim(' - hotkey: Press keyboard shortcuts'));
|
|
1238
|
+
console.log(colors.textDim(' - scroll: Scroll up/down/left/right'));
|
|
1239
|
+
console.log(colors.textDim(' - wait: Wait for specified time'));
|
|
1240
|
+
console.log(colors.textDim(' - finished: Complete the task'));
|
|
1241
|
+
console.log('');
|
|
1242
|
+
console.log(colors.primaryBright('Use the GUI tools in the interactive session to control the computer.'));
|
|
1243
|
+
console.log('');
|
|
1244
|
+
} catch (error: any) {
|
|
1245
|
+
const { message, suggestion } = formatError(error);
|
|
1246
|
+
console.log('');
|
|
1247
|
+
console.log(colors.error(`Failed to start GUI Subagent: ${message}`));
|
|
1248
|
+
console.log(colors.textMuted(suggestion));
|
|
1249
|
+
console.log('');
|
|
1250
|
+
}
|
|
1251
|
+
});
|
|
1252
|
+
|
|
1253
|
+
program
|
|
1254
|
+
.command('memory')
|
|
1255
|
+
.description('Manage memory files (list or clean)')
|
|
1256
|
+
.option('-l, --list', 'List all memory files')
|
|
1257
|
+
.option('--clean', 'Clean all project memories (keep global memory)')
|
|
1258
|
+
.option('--clean-project', 'Clean the current project\'s memory only')
|
|
1259
|
+
.option('--clean-all', 'Clean all memories (including global memory)')
|
|
1260
|
+
.action(async (options) => {
|
|
1261
|
+
const separator = icons.separator.repeat(40);
|
|
1262
|
+
console.log('');
|
|
1263
|
+
console.log(colors.primaryBright(`${icons.folder} Memory Management`));
|
|
1264
|
+
console.log(colors.border(separator));
|
|
1265
|
+
console.log('');
|
|
1266
|
+
|
|
1267
|
+
const { getMemoryManager } = await import('./memory.js');
|
|
1268
|
+
const memoryManager = getMemoryManager(process.cwd());
|
|
1269
|
+
const memoriesDir = memoryManager.getMemoriesDir();
|
|
1270
|
+
|
|
1271
|
+
// Helper to get memory info
|
|
1272
|
+
const getMemoryInfo = (fileName: string) => {
|
|
1273
|
+
if (fileName === 'global.md') {
|
|
1274
|
+
return { type: 'global', description: 'Global memory (shared across all projects)' };
|
|
1275
|
+
}
|
|
1276
|
+
const match = fileName.match(/^project_(.+)_\w{16}\.md$/);
|
|
1277
|
+
if (match) {
|
|
1278
|
+
return { type: 'project', description: `Project: ${match[1]}` };
|
|
1279
|
+
}
|
|
1280
|
+
return { type: 'unknown', description: fileName };
|
|
1281
|
+
};
|
|
1282
|
+
|
|
1283
|
+
if (options.list) {
|
|
1284
|
+
// List all memory files
|
|
1285
|
+
console.log(colors.textMuted(`Memory directory: ${memoriesDir}`));
|
|
1286
|
+
console.log('');
|
|
1287
|
+
|
|
1288
|
+
try {
|
|
1289
|
+
const files = await fs.readdir(memoriesDir).catch(() => []);
|
|
1290
|
+
if (files.length === 0) {
|
|
1291
|
+
console.log(colors.textMuted('No memory files found.'));
|
|
1292
|
+
console.log('');
|
|
1293
|
+
process.exit(0);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
const globalFile = files.find(f => f === 'global.md');
|
|
1297
|
+
const projectFiles = files.filter(f => f.startsWith('project_'));
|
|
1298
|
+
|
|
1299
|
+
if (globalFile) {
|
|
1300
|
+
const info = getMemoryInfo(globalFile);
|
|
1301
|
+
console.log(` ${colors.success(icons.success)} ${colors.primaryBright('global.md')}`);
|
|
1302
|
+
console.log(` ${colors.textDim(` ${info.description}`)}`);
|
|
1303
|
+
console.log('');
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
if (projectFiles.length > 0) {
|
|
1307
|
+
console.log(colors.primaryBright(` Project Memories (${projectFiles.length})`));
|
|
1308
|
+
console.log('');
|
|
1309
|
+
|
|
1310
|
+
for (const file of projectFiles) {
|
|
1311
|
+
const info = getMemoryInfo(file);
|
|
1312
|
+
const filePath = join(memoriesDir, file);
|
|
1313
|
+
try {
|
|
1314
|
+
const stat = await fs.stat(filePath);
|
|
1315
|
+
const size = stat.size;
|
|
1316
|
+
const sizeStr = size < 1024 ? `${size} B` : `${(size / 1024).toFixed(1)} KB`;
|
|
1317
|
+
console.log(` ${colors.success(icons.success)} ${colors.primaryBright(file)}`);
|
|
1318
|
+
console.log(` ${colors.textDim(` ${info.description} | Size: ${sizeStr}`)}`);
|
|
1319
|
+
} catch {
|
|
1320
|
+
console.log(` ${colors.success(icons.success)} ${colors.primaryBright(file)}`);
|
|
1321
|
+
console.log(` ${colors.textDim(` ${info.description}`)}`);
|
|
1322
|
+
}
|
|
1323
|
+
console.log('');
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
console.log(colors.textMuted(`Total: ${files.length} memory file(s)`));
|
|
1328
|
+
console.log('');
|
|
1329
|
+
} catch {
|
|
1330
|
+
console.log(colors.textMuted('No memory files found.'));
|
|
1331
|
+
console.log('');
|
|
1332
|
+
}
|
|
1333
|
+
} else if (options.clean) {
|
|
1334
|
+
// Clean all project memories (keep global.md)
|
|
1335
|
+
console.log(colors.textMuted('Cleaning all project memories...'));
|
|
1336
|
+
console.log(colors.textMuted(`Keeping: ${colors.primaryBright('global.md')}`));
|
|
1337
|
+
console.log('');
|
|
1338
|
+
|
|
1339
|
+
try {
|
|
1340
|
+
const files = await fs.readdir(memoriesDir).catch(() => []);
|
|
1341
|
+
const projectFiles = files.filter(f => f.startsWith('project_'));
|
|
1342
|
+
|
|
1343
|
+
if (projectFiles.length === 0) {
|
|
1344
|
+
console.log(colors.textMuted('No project memories to clean.'));
|
|
1345
|
+
console.log('');
|
|
1346
|
+
process.exit(0);
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
let cleaned = 0;
|
|
1350
|
+
for (const file of projectFiles) {
|
|
1351
|
+
await fs.unlink(join(memoriesDir, file));
|
|
1352
|
+
cleaned++;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
console.log(colors.success(`✅ Cleaned ${cleaned} project memory file(s)`));
|
|
1356
|
+
// TODO: 如果需要自动重建 project memory,取消下面注释
|
|
1357
|
+
// await memoryManager.saveMemory('# Project Context\n\nProject-specific context will be added here.', 'project');
|
|
1358
|
+
// console.log(colors.textMuted(' Recreated current project memory'));
|
|
1359
|
+
console.log(colors.textMuted(' Use /init to initialize if needed'));
|
|
1360
|
+
console.log('');
|
|
1361
|
+
} catch (error: any) {
|
|
1362
|
+
const { message, suggestion } = formatError(error);
|
|
1363
|
+
console.log(colors.error(`Failed to clean project memories: ${message}`));
|
|
1364
|
+
console.log(colors.textMuted(suggestion));
|
|
1365
|
+
console.log('');
|
|
1366
|
+
}
|
|
1367
|
+
} else if (options.cleanProject) {
|
|
1368
|
+
// Clean only the current project's memory
|
|
1369
|
+
console.log(colors.textMuted(`Cleaning current project memory...`));
|
|
1370
|
+
console.log(colors.textMuted(`Project: ${colors.primaryBright(process.cwd())}`));
|
|
1371
|
+
console.log('');
|
|
1372
|
+
|
|
1373
|
+
try {
|
|
1374
|
+
// Find and delete the current project's memory file
|
|
1375
|
+
const memoryFiles = memoryManager.getMemoryFiles();
|
|
1376
|
+
const currentProjectMemory = memoryFiles.find(m => m.level === 'project');
|
|
1377
|
+
|
|
1378
|
+
if (currentProjectMemory) {
|
|
1379
|
+
await fs.unlink(currentProjectMemory.path);
|
|
1380
|
+
console.log(colors.success(`✅ Cleaned current project memory`));
|
|
1381
|
+
console.log(colors.textMuted(` File: ${path.basename(currentProjectMemory.path)}`));
|
|
1382
|
+
} else {
|
|
1383
|
+
console.log(colors.textMuted('No memory found for the current project.'));
|
|
1384
|
+
}
|
|
1385
|
+
// TODO: 如果需要自动重建 project memory,取消下面注释
|
|
1386
|
+
// await memoryManager.saveMemory('# Project Context\n\nProject-specific context will be added here.', 'project');
|
|
1387
|
+
// console.log(colors.textMuted(' Recreated current project memory'));
|
|
1388
|
+
console.log(colors.textMuted(' Use /init to initialize if needed'));
|
|
1389
|
+
console.log('');
|
|
1390
|
+
} catch (error: any) {
|
|
1391
|
+
const { message, suggestion } = formatError(error);
|
|
1392
|
+
console.log(colors.error(`Failed to clean project memory: ${message}`));
|
|
1393
|
+
console.log(colors.textMuted(suggestion));
|
|
1394
|
+
console.log('');
|
|
1395
|
+
}
|
|
1396
|
+
} else if (options.cleanAll) {
|
|
1397
|
+
// Clean all memories including global
|
|
1398
|
+
console.log(colors.warning(`${icons.warning} This will delete ALL memory files including global memory.`));
|
|
1399
|
+
console.log('');
|
|
1400
|
+
console.log(colors.textMuted('Files to be deleted:'));
|
|
1401
|
+
console.log(colors.textMuted(` - global.md (global memory)`));
|
|
1402
|
+
console.log(colors.textMuted(` - all project memories`));
|
|
1403
|
+
console.log('');
|
|
1404
|
+
|
|
1405
|
+
try {
|
|
1406
|
+
const files = await fs.readdir(memoriesDir).catch(() => []);
|
|
1407
|
+
if (files.length === 0) {
|
|
1408
|
+
console.log(colors.textMuted('No memory files to clean.'));
|
|
1409
|
+
console.log('');
|
|
1410
|
+
process.exit(0);
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
let cleaned = 0;
|
|
1414
|
+
for (const file of files) {
|
|
1415
|
+
await fs.unlink(join(memoriesDir, file));
|
|
1416
|
+
cleaned++;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
// Recreate global memory (always keep global memory available)
|
|
1420
|
+
await memoryManager.saveMemory('# Global Context\n\nGlobal preferences and settings will be added here.', 'global');
|
|
1421
|
+
// TODO: 如果需要同时重建 project memory,取消下面注释
|
|
1422
|
+
// await memoryManager.saveMemory('# Project Context\n\nProject-specific context will be added here.', 'project');
|
|
1423
|
+
|
|
1424
|
+
console.log(colors.success(`✅ Cleaned ${cleaned} memory file(s)`));
|
|
1425
|
+
console.log(colors.textMuted(' Recreated global memory'));
|
|
1426
|
+
console.log(colors.textMuted(' Use /init to initialize project memory if needed'));
|
|
1427
|
+
console.log('');
|
|
1428
|
+
} catch (error: any) {
|
|
1429
|
+
const { message, suggestion } = formatError(error);
|
|
1430
|
+
console.log(colors.error(`Failed to clean memories: ${message}`));
|
|
1431
|
+
console.log(colors.textMuted(suggestion));
|
|
1432
|
+
console.log('');
|
|
1433
|
+
}
|
|
1434
|
+
} else {
|
|
1435
|
+
// No option specified, show help
|
|
1436
|
+
console.log(colors.textMuted('Usage:'));
|
|
1437
|
+
console.log(` ${colors.primaryBright('xagent memory -l')} ${colors.textDim('| List all memory files')}`);
|
|
1438
|
+
console.log(` ${colors.primaryBright('xagent memory --clean')} ${colors.textDim('| Clean all project memories (keep global)')}`);
|
|
1439
|
+
console.log(` ${colors.primaryBright('xagent memory --clean-project')} ${colors.textDim('| Clean current project memory only')}`);
|
|
1440
|
+
console.log(` ${colors.primaryBright('xagent memory --clean-all')} ${colors.textDim('| Clean ALL memories (including global)')}`);
|
|
1441
|
+
console.log('');
|
|
1442
|
+
}
|
|
1443
|
+
});
|
|
1444
|
+
|
|
1445
|
+
program
|
|
1446
|
+
.command('update')
|
|
1447
|
+
.description('Check for updates and update xAgent CLI')
|
|
1448
|
+
.action(async () => {
|
|
1449
|
+
const separator = icons.separator.repeat(40);
|
|
1450
|
+
console.log('');
|
|
1451
|
+
console.log(colors.primaryBright(`${icons.rocket} Update Check`));
|
|
1452
|
+
console.log(colors.border(separator));
|
|
1453
|
+
console.log('');
|
|
1454
|
+
|
|
1455
|
+
try {
|
|
1456
|
+
const { getUpdateManager } = await import('./update.js');
|
|
1457
|
+
const updateManager = getUpdateManager();
|
|
1458
|
+
const versionInfo = await updateManager.checkForUpdates();
|
|
1459
|
+
|
|
1460
|
+
console.log(` ${icons.info} ${colors.textMuted('Current version:')} ${colors.primaryBright(versionInfo.currentVersion)}`);
|
|
1461
|
+
console.log(` ${icons.code} ${colors.textMuted('Latest version:')} ${colors.primaryBright(versionInfo.latestVersion)}`);
|
|
1462
|
+
console.log('');
|
|
1463
|
+
|
|
1464
|
+
if (versionInfo.updateAvailable) {
|
|
1465
|
+
console.log(colors.success(` 📦 A new version is available!`));
|
|
1466
|
+
console.log('');
|
|
1467
|
+
|
|
1468
|
+
if (versionInfo.releaseNotes) {
|
|
1469
|
+
console.log(colors.textMuted(' Release Notes:'));
|
|
1470
|
+
console.log(colors.textDim(` ${versionInfo.releaseNotes}`));
|
|
1471
|
+
console.log('');
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
const shouldUpdate = await confirm({
|
|
1475
|
+
message: 'Do you want to update now?',
|
|
1476
|
+
});
|
|
1477
|
+
|
|
1478
|
+
if (shouldUpdate === true) {
|
|
1479
|
+
console.log('');
|
|
1480
|
+
await updateManager.autoUpdate();
|
|
1481
|
+
process.exit(0);
|
|
1482
|
+
}
|
|
1483
|
+
} else {
|
|
1484
|
+
console.log(colors.success(` ✅ You are using the latest version`));
|
|
1485
|
+
console.log('');
|
|
1486
|
+
process.exit(0);
|
|
1487
|
+
}
|
|
1488
|
+
} catch (error: any) {
|
|
1489
|
+
console.log(colors.error(` ❌ Failed to check for updates: ${error.message}`));
|
|
1490
|
+
console.log('');
|
|
1491
|
+
}
|
|
1492
|
+
});
|
|
1493
|
+
|
|
1494
|
+
program.parse(process.argv);
|
|
1495
|
+
|
|
1496
|
+
if (!process.argv.slice(2).length) {
|
|
1497
|
+
program.outputHelp();
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
// ============================================================
|
|
1501
|
+
// Global error handling - prevent crashes from uncaught errors
|
|
1502
|
+
// ============================================================
|
|
1503
|
+
|
|
1504
|
+
// Handle uncaught promise rejections
|
|
1505
|
+
process.on('unhandledRejection', (reason: any, _promise: Promise<any>) => {
|
|
1506
|
+
console.error('\n❌ An unexpected error occurred');
|
|
1507
|
+
if (reason instanceof Error) {
|
|
1508
|
+
console.error(` ${reason.message}`);
|
|
1509
|
+
} else if (reason) {
|
|
1510
|
+
console.error(` ${String(reason)}`);
|
|
1511
|
+
}
|
|
1512
|
+
console.error('\n If this problem persists, please report this issue.');
|
|
1513
|
+
console.error('');
|
|
1514
|
+
process.exit(1);
|
|
1515
|
+
});
|
|
1516
|
+
|
|
1517
|
+
// Handle uncaught exceptions
|
|
1518
|
+
process.on('uncaughtException', (error: Error) => {
|
|
1519
|
+
console.error('\n❌ Critical error - application will exit');
|
|
1520
|
+
console.error(` ${error.message}`);
|
|
1521
|
+
console.error('');
|
|
1522
|
+
process.exit(1);
|
|
1523
|
+
});
|