@xagent-ai/cli 1.0.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/.eslintrc.js +25 -0
- package/.gitmodules +3 -0
- package/.prettierrc.json +8 -0
- package/CONTRIBUTING.md +167 -0
- package/LICENSE +21 -0
- package/README.md +280 -0
- package/README_CN.md +280 -0
- package/dist/agents.d.ts +21 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +463 -0
- package/dist/agents.js.map +1 -0
- package/dist/ai-client.d.ts +83 -0
- package/dist/ai-client.d.ts.map +1 -0
- package/dist/ai-client.js +1280 -0
- package/dist/ai-client.js.map +1 -0
- package/dist/auth.d.ts +25 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +573 -0
- package/dist/auth.js.map +1 -0
- package/dist/cancellation.d.ts +46 -0
- package/dist/cancellation.d.ts.map +1 -0
- package/dist/cancellation.js +154 -0
- package/dist/cancellation.js.map +1 -0
- package/dist/checkpoint.d.ts +28 -0
- package/dist/checkpoint.d.ts.map +1 -0
- package/dist/checkpoint.js +186 -0
- package/dist/checkpoint.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +364 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +49 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +205 -0
- package/dist/config.js.map +1 -0
- package/dist/context-compressor.d.ts +51 -0
- package/dist/context-compressor.d.ts.map +1 -0
- package/dist/context-compressor.js +231 -0
- package/dist/context-compressor.js.map +1 -0
- package/dist/conversation.d.ts +34 -0
- package/dist/conversation.d.ts.map +1 -0
- package/dist/conversation.js +221 -0
- package/dist/conversation.js.map +1 -0
- package/dist/gui-subagent/action-parser/actionParser.d.ts +19 -0
- package/dist/gui-subagent/action-parser/actionParser.d.ts.map +1 -0
- package/dist/gui-subagent/action-parser/actionParser.js +203 -0
- package/dist/gui-subagent/action-parser/actionParser.js.map +1 -0
- package/dist/gui-subagent/action-parser/constants.d.ts +8 -0
- package/dist/gui-subagent/action-parser/constants.d.ts.map +1 -0
- package/dist/gui-subagent/action-parser/constants.js +12 -0
- package/dist/gui-subagent/action-parser/constants.js.map +1 -0
- package/dist/gui-subagent/action-parser/index.d.ts +3 -0
- package/dist/gui-subagent/action-parser/index.d.ts.map +1 -0
- package/dist/gui-subagent/action-parser/index.js +6 -0
- package/dist/gui-subagent/action-parser/index.js.map +1 -0
- package/dist/gui-subagent/action-parser/types.d.ts +24 -0
- package/dist/gui-subagent/action-parser/types.d.ts.map +1 -0
- package/dist/gui-subagent/action-parser/types.js +12 -0
- package/dist/gui-subagent/action-parser/types.js.map +1 -0
- package/dist/gui-subagent/agent/gui-agent.d.ts +126 -0
- package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -0
- package/dist/gui-subagent/agent/gui-agent.js +820 -0
- package/dist/gui-subagent/agent/gui-agent.js.map +1 -0
- package/dist/gui-subagent/agent/index.d.ts +5 -0
- package/dist/gui-subagent/agent/index.d.ts.map +1 -0
- package/dist/gui-subagent/agent/index.js +5 -0
- package/dist/gui-subagent/agent/index.js.map +1 -0
- package/dist/gui-subagent/index.d.ts +43 -0
- package/dist/gui-subagent/index.d.ts.map +1 -0
- package/dist/gui-subagent/index.js +96 -0
- package/dist/gui-subagent/index.js.map +1 -0
- package/dist/gui-subagent/operator/base-operator.d.ts +108 -0
- package/dist/gui-subagent/operator/base-operator.d.ts.map +1 -0
- package/dist/gui-subagent/operator/base-operator.js +172 -0
- package/dist/gui-subagent/operator/base-operator.js.map +1 -0
- package/dist/gui-subagent/operator/browser-operator.d.ts +36 -0
- package/dist/gui-subagent/operator/browser-operator.d.ts.map +1 -0
- package/dist/gui-subagent/operator/browser-operator.js +306 -0
- package/dist/gui-subagent/operator/browser-operator.js.map +1 -0
- package/dist/gui-subagent/operator/computer-operator.d.ts +31 -0
- package/dist/gui-subagent/operator/computer-operator.d.ts.map +1 -0
- package/dist/gui-subagent/operator/computer-operator.js +441 -0
- package/dist/gui-subagent/operator/computer-operator.js.map +1 -0
- package/dist/gui-subagent/operator/desktop-operator.d.ts +55 -0
- package/dist/gui-subagent/operator/desktop-operator.d.ts.map +1 -0
- package/dist/gui-subagent/operator/desktop-operator.js +527 -0
- package/dist/gui-subagent/operator/desktop-operator.js.map +1 -0
- package/dist/gui-subagent/operator/index.d.ts +7 -0
- package/dist/gui-subagent/operator/index.d.ts.map +1 -0
- package/dist/gui-subagent/operator/index.js +6 -0
- package/dist/gui-subagent/operator/index.js.map +1 -0
- package/dist/gui-subagent/types/actions.d.ts +108 -0
- package/dist/gui-subagent/types/actions.d.ts.map +1 -0
- package/dist/gui-subagent/types/actions.js +39 -0
- package/dist/gui-subagent/types/actions.js.map +1 -0
- package/dist/gui-subagent/types/index.d.ts +6 -0
- package/dist/gui-subagent/types/index.d.ts.map +1 -0
- package/dist/gui-subagent/types/index.js +6 -0
- package/dist/gui-subagent/types/index.js.map +1 -0
- package/dist/gui-subagent/types/operator.d.ts +95 -0
- package/dist/gui-subagent/types/operator.d.ts.map +1 -0
- package/dist/gui-subagent/types/operator.js +16 -0
- package/dist/gui-subagent/types/operator.js.map +1 -0
- package/dist/gui-subagent/utils.d.ts +19 -0
- package/dist/gui-subagent/utils.d.ts.map +1 -0
- package/dist/gui-subagent/utils.js +42 -0
- package/dist/gui-subagent/utils.js.map +1 -0
- package/dist/hook.d.ts +73 -0
- package/dist/hook.d.ts.map +1 -0
- package/dist/hook.js +156 -0
- package/dist/hook.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/input-history.d.ts +24 -0
- package/dist/input-history.d.ts.map +1 -0
- package/dist/input-history.js +94 -0
- package/dist/input-history.js.map +1 -0
- package/dist/input-processor.d.ts +31 -0
- package/dist/input-processor.d.ts.map +1 -0
- package/dist/input-processor.js +233 -0
- package/dist/input-processor.js.map +1 -0
- package/dist/keyboard-manager.d.ts +151 -0
- package/dist/keyboard-manager.d.ts.map +1 -0
- package/dist/keyboard-manager.js +396 -0
- package/dist/keyboard-manager.js.map +1 -0
- package/dist/logger.d.ts +75 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +339 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp.d.ts +57 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +483 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory.d.ts +25 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +250 -0
- package/dist/memory.js.map +1 -0
- package/dist/print-system-prompt.d.ts +2 -0
- package/dist/print-system-prompt.d.ts.map +1 -0
- package/dist/print-system-prompt.js +40 -0
- package/dist/print-system-prompt.js.map +1 -0
- package/dist/session-manager.d.ts +41 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +234 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/session.d.ts +77 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +1081 -0
- package/dist/session.js.map +1 -0
- package/dist/skill-invoker.d.ts +177 -0
- package/dist/skill-invoker.d.ts.map +1 -0
- package/dist/skill-invoker.js +1643 -0
- package/dist/skill-invoker.js.map +1 -0
- package/dist/skill-loader.d.ts +76 -0
- package/dist/skill-loader.d.ts.map +1 -0
- package/dist/skill-loader.js +407 -0
- package/dist/skill-loader.js.map +1 -0
- package/dist/slash-commands.d.ts +60 -0
- package/dist/slash-commands.d.ts.map +1 -0
- package/dist/slash-commands.js +1021 -0
- package/dist/slash-commands.js.map +1 -0
- package/dist/smart-approval.d.ts +137 -0
- package/dist/smart-approval.d.ts.map +1 -0
- package/dist/smart-approval.js +512 -0
- package/dist/smart-approval.js.map +1 -0
- package/dist/system-prompt-generator.d.ts +35 -0
- package/dist/system-prompt-generator.d.ts.map +1 -0
- package/dist/system-prompt-generator.js +729 -0
- package/dist/system-prompt-generator.js.map +1 -0
- package/dist/test-boundary-conditions.d.ts.map +1 -0
- package/dist/test-boundary-conditions.js.map +1 -0
- package/dist/test-cancellation-fix.d.ts.map +1 -0
- package/dist/test-cancellation-fix.js.map +1 -0
- package/dist/test-input-history.d.ts.map +1 -0
- package/dist/test-input-history.js.map +1 -0
- package/dist/test-interaction-flow.d.ts.map +1 -0
- package/dist/test-interaction-flow.js.map +1 -0
- package/dist/test-quick.d.ts.map +1 -0
- package/dist/test-quick.js.map +1 -0
- package/dist/test-user-interaction.d.ts.map +1 -0
- package/dist/test-user-interaction.js.map +1 -0
- package/dist/theme.d.ts +353 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +383 -0
- package/dist/theme.js.map +1 -0
- package/dist/tools.d.ts +373 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +2906 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +180 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/dist/unified-session.d.ts +42 -0
- package/dist/unified-session.d.ts.map +1 -0
- package/dist/unified-session.js +271 -0
- package/dist/unified-session.js.map +1 -0
- package/dist/update.d.ts +30 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +211 -0
- package/dist/update.js.map +1 -0
- package/dist/workflow.d.ts +53 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +405 -0
- package/dist/workflow.js.map +1 -0
- package/docs/architecture/mcp-integration-guide.md +131 -0
- package/docs/architecture/overview.md +93 -0
- package/docs/architecture/tool-system-design.md +89 -0
- package/docs/cli/commands.md +189 -0
- package/docs/smart-mode.md +257 -0
- package/docs/third-party-models.md +449 -0
- package/package.json +85 -0
- package/scripts/init-skills-path.js +58 -0
- package/skills/.claude-plugin/marketplace.json +45 -0
- package/skills/README.md +94 -0
- package/skills/THIRD_PARTY_NOTICES.md +405 -0
- package/skills/skills/algorithmic-art/LICENSE.txt +202 -0
- package/skills/skills/algorithmic-art/SKILL.md +405 -0
- package/skills/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/skills/skills/algorithmic-art/templates/viewer.html +599 -0
- package/skills/skills/brand-guidelines/LICENSE.txt +202 -0
- package/skills/skills/brand-guidelines/SKILL.md +73 -0
- package/skills/skills/canvas-design/LICENSE.txt +202 -0
- package/skills/skills/canvas-design/SKILL.md +130 -0
- package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- 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 +93 -0
- package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- 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 +93 -0
- 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 +93 -0
- package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/skills/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- 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 +93 -0
- package/skills/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- 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 +93 -0
- 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 +93 -0
- 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 +93 -0
- 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 +93 -0
- 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 +93 -0
- package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- 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 +93 -0
- 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 +93 -0
- package/skills/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- 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 +93 -0
- 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 +93 -0
- package/skills/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- 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 +93 -0
- package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- 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 +93 -0
- package/skills/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- 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 +93 -0
- package/skills/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/skills/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/skills/skills/doc-coauthoring/SKILL.md +375 -0
- package/skills/skills/docx/LICENSE.txt +30 -0
- package/skills/skills/docx/SKILL.md +197 -0
- package/skills/skills/docx/docx-js.md +350 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/skills/docx/ooxml/scripts/pack.py +159 -0
- package/skills/skills/docx/ooxml/scripts/unpack.py +29 -0
- package/skills/skills/docx/ooxml/scripts/validate.py +69 -0
- package/skills/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/skills/docx/ooxml/scripts/validation/base.py +951 -0
- package/skills/skills/docx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/skills/docx/ooxml.md +610 -0
- package/skills/skills/docx/scripts/__init__.py +1 -0
- package/skills/skills/docx/scripts/document.py +1276 -0
- package/skills/skills/docx/scripts/templates/comments.xml +3 -0
- package/skills/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/skills/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/skills/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/skills/skills/docx/scripts/templates/people.xml +3 -0
- package/skills/skills/docx/scripts/utilities.py +374 -0
- package/skills/skills/frontend-design/LICENSE.txt +177 -0
- package/skills/skills/frontend-design/SKILL.md +42 -0
- package/skills/skills/internal-comms/LICENSE.txt +202 -0
- package/skills/skills/internal-comms/SKILL.md +32 -0
- package/skills/skills/internal-comms/examples/3p-updates.md +47 -0
- package/skills/skills/internal-comms/examples/company-newsletter.md +65 -0
- package/skills/skills/internal-comms/examples/faq-answers.md +30 -0
- package/skills/skills/internal-comms/examples/general-comms.md +16 -0
- package/skills/skills/mcp-builder/LICENSE.txt +202 -0
- package/skills/skills/mcp-builder/SKILL.md +236 -0
- package/skills/skills/mcp-builder/reference/evaluation.md +602 -0
- package/skills/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/skills/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/skills/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/skills/skills/mcp-builder/scripts/connections.py +151 -0
- package/skills/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/skills/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/skills/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/skills/skills/pdf/LICENSE.txt +30 -0
- package/skills/skills/pdf/SKILL.md +294 -0
- package/skills/skills/pdf/forms.md +205 -0
- package/skills/skills/pdf/reference.md +612 -0
- package/skills/skills/pdf/scripts/check_bounding_boxes.py +70 -0
- package/skills/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/skills/skills/pdf/scripts/check_fillable_fields.py +12 -0
- package/skills/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/skills/skills/pdf/scripts/create_validation_image.py +41 -0
- package/skills/skills/pdf/scripts/extract_form_field_info.py +152 -0
- package/skills/skills/pdf/scripts/fill_fillable_fields.py +114 -0
- package/skills/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/skills/skills/pptx/LICENSE.txt +30 -0
- package/skills/skills/pptx/SKILL.md +484 -0
- package/skills/skills/pptx/html2pptx.md +625 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/skills/pptx/ooxml/scripts/pack.py +159 -0
- package/skills/skills/pptx/ooxml/scripts/unpack.py +29 -0
- package/skills/skills/pptx/ooxml/scripts/validate.py +69 -0
- package/skills/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/skills/pptx/ooxml/scripts/validation/base.py +951 -0
- package/skills/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/skills/pptx/ooxml.md +427 -0
- package/skills/skills/pptx/scripts/html2pptx.js +979 -0
- package/skills/skills/pptx/scripts/inventory.py +1020 -0
- package/skills/skills/pptx/scripts/rearrange.py +231 -0
- package/skills/skills/pptx/scripts/replace.py +385 -0
- package/skills/skills/pptx/scripts/thumbnail.py +450 -0
- package/skills/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skills/skill-creator/SKILL.md +356 -0
- package/skills/skills/skill-creator/references/output-patterns.md +82 -0
- package/skills/skills/skill-creator/references/workflows.md +28 -0
- package/skills/skills/skill-creator/scripts/init_skill.py +303 -0
- package/skills/skills/skill-creator/scripts/package_skill.py +110 -0
- package/skills/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/skills/skills/slack-gif-creator/LICENSE.txt +202 -0
- package/skills/skills/slack-gif-creator/SKILL.md +254 -0
- package/skills/skills/slack-gif-creator/core/easing.py +234 -0
- package/skills/skills/slack-gif-creator/core/frame_composer.py +176 -0
- package/skills/skills/slack-gif-creator/core/gif_builder.py +269 -0
- package/skills/skills/slack-gif-creator/core/validators.py +136 -0
- package/skills/skills/slack-gif-creator/requirements.txt +4 -0
- package/skills/skills/theme-factory/LICENSE.txt +202 -0
- package/skills/skills/theme-factory/SKILL.md +59 -0
- package/skills/skills/theme-factory/theme-showcase.pdf +0 -0
- package/skills/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/skills/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/skills/skills/theme-factory/themes/desert-rose.md +19 -0
- package/skills/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/skills/skills/theme-factory/themes/golden-hour.md +19 -0
- package/skills/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/skills/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/skills/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/skills/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/skills/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/skills/skills/web-artifacts-builder/LICENSE.txt +202 -0
- package/skills/skills/web-artifacts-builder/SKILL.md +74 -0
- package/skills/skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/skills/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/skills/skills/webapp-testing/LICENSE.txt +202 -0
- package/skills/skills/webapp-testing/SKILL.md +96 -0
- package/skills/skills/webapp-testing/examples/console_logging.py +35 -0
- package/skills/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/skills/webapp-testing/scripts/with_server.py +106 -0
- package/skills/skills/xlsx/LICENSE.txt +30 -0
- package/skills/skills/xlsx/SKILL.md +289 -0
- package/skills/skills/xlsx/recalc.py +178 -0
- package/skills/spec/agent-skills-spec.md +3 -0
- package/skills/template/SKILL.md +6 -0
- package/src/agents.ts +504 -0
- package/src/ai-client.ts +1456 -0
- package/src/auth.ts +648 -0
- package/src/cancellation.ts +176 -0
- package/src/checkpoint.ts +219 -0
- package/src/cli.ts +384 -0
- package/src/config.ts +248 -0
- package/src/context-compressor.ts +290 -0
- package/src/conversation.ts +288 -0
- package/src/gui-subagent/action-parser/actionParser.ts +312 -0
- package/src/gui-subagent/action-parser/constants.ts +12 -0
- package/src/gui-subagent/action-parser/index.ts +6 -0
- package/src/gui-subagent/action-parser/types.ts +31 -0
- package/src/gui-subagent/agent/gui-agent.ts +982 -0
- package/src/gui-subagent/agent/index.ts +5 -0
- package/src/gui-subagent/index.ts +139 -0
- package/src/gui-subagent/operator/base-operator.ts +246 -0
- package/src/gui-subagent/operator/computer-operator.ts +520 -0
- package/src/gui-subagent/operator/index.ts +7 -0
- package/src/gui-subagent/types/actions.ts +263 -0
- package/src/gui-subagent/types/index.ts +6 -0
- package/src/gui-subagent/types/operator.ts +106 -0
- package/src/gui-subagent/utils.ts +51 -0
- package/src/index.ts +18 -0
- package/src/input-processor.ts +282 -0
- package/src/logger.ts +438 -0
- package/src/mcp.ts +563 -0
- package/src/memory.ts +303 -0
- package/src/session-manager.ts +308 -0
- package/src/session.ts +1280 -0
- package/src/skill-invoker.ts +1888 -0
- package/src/skill-loader.ts +476 -0
- package/src/slash-commands.ts +1150 -0
- package/src/smart-approval.ts +595 -0
- package/src/system-prompt-generator.ts +786 -0
- package/src/theme.ts +455 -0
- package/src/tools.ts +3398 -0
- package/src/types.ts +198 -0
- package/src/update.ts +270 -0
- package/src/workflow.ts +508 -0
- package/tsconfig.json +22 -0
- package/vitest.config.ts +19 -0
package/dist/session.js
ADDED
|
@@ -0,0 +1,1081 @@
|
|
|
1
|
+
import readline from 'readline';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { ExecutionMode, AuthType } from './types.js';
|
|
5
|
+
import { AIClient, detectThinkingKeywords, getThinkingTokens } from './ai-client.js';
|
|
6
|
+
import { getConfigManager } from './config.js';
|
|
7
|
+
import { AuthService, selectAuthType } from './auth.js';
|
|
8
|
+
import { getToolRegistry } from './tools.js';
|
|
9
|
+
import { getAgentManager } from './agents.js';
|
|
10
|
+
import { getMemoryManager } from './memory.js';
|
|
11
|
+
import { getMCPManager } from './mcp.js';
|
|
12
|
+
import { getCheckpointManager } from './checkpoint.js';
|
|
13
|
+
import { getConversationManager } from './conversation.js';
|
|
14
|
+
import { getSessionManager } from './session-manager.js';
|
|
15
|
+
import { SlashCommandHandler, parseInput } from './slash-commands.js';
|
|
16
|
+
import { SystemPromptGenerator } from './system-prompt-generator.js';
|
|
17
|
+
import { theme, icons, colors, styleHelpers, renderMarkdown } from './theme.js';
|
|
18
|
+
import { getCancellationManager } from './cancellation.js';
|
|
19
|
+
import { getContextCompressor } from './context-compressor.js';
|
|
20
|
+
export class InteractiveSession {
|
|
21
|
+
conversationManager;
|
|
22
|
+
sessionManager;
|
|
23
|
+
contextCompressor;
|
|
24
|
+
rl;
|
|
25
|
+
aiClient = null;
|
|
26
|
+
conversation = [];
|
|
27
|
+
toolCalls = [];
|
|
28
|
+
executionMode;
|
|
29
|
+
slashCommandHandler;
|
|
30
|
+
configManager;
|
|
31
|
+
agentManager;
|
|
32
|
+
memoryManager;
|
|
33
|
+
mcpManager;
|
|
34
|
+
checkpointManager;
|
|
35
|
+
currentAgent = null;
|
|
36
|
+
cancellationManager;
|
|
37
|
+
indentLevel;
|
|
38
|
+
indentString;
|
|
39
|
+
constructor(indentLevel = 0) {
|
|
40
|
+
this.rl = readline.createInterface({
|
|
41
|
+
input: process.stdin,
|
|
42
|
+
output: process.stdout
|
|
43
|
+
});
|
|
44
|
+
this.configManager = getConfigManager(process.cwd());
|
|
45
|
+
this.agentManager = getAgentManager(process.cwd());
|
|
46
|
+
this.memoryManager = getMemoryManager(process.cwd());
|
|
47
|
+
this.mcpManager = getMCPManager();
|
|
48
|
+
this.checkpointManager = getCheckpointManager(process.cwd());
|
|
49
|
+
this.conversationManager = getConversationManager();
|
|
50
|
+
this.sessionManager = getSessionManager(process.cwd());
|
|
51
|
+
this.slashCommandHandler = new SlashCommandHandler();
|
|
52
|
+
// 注册 /clear 回调,清除对话时同步清空本地 conversation
|
|
53
|
+
this.slashCommandHandler.setClearCallback(() => {
|
|
54
|
+
this.conversation = [];
|
|
55
|
+
});
|
|
56
|
+
// 注册 MCP 更新回调,更新系统提示
|
|
57
|
+
this.slashCommandHandler.setSystemPromptUpdateCallback(async () => {
|
|
58
|
+
await this.updateSystemPrompt();
|
|
59
|
+
});
|
|
60
|
+
this.executionMode = ExecutionMode.DEFAULT;
|
|
61
|
+
this.cancellationManager = getCancellationManager();
|
|
62
|
+
this.indentLevel = indentLevel;
|
|
63
|
+
this.indentString = ' '.repeat(indentLevel);
|
|
64
|
+
this.contextCompressor = getContextCompressor();
|
|
65
|
+
}
|
|
66
|
+
getIndent() {
|
|
67
|
+
return this.indentString;
|
|
68
|
+
}
|
|
69
|
+
setAIClient(aiClient) {
|
|
70
|
+
this.aiClient = aiClient;
|
|
71
|
+
}
|
|
72
|
+
setExecutionMode(mode) {
|
|
73
|
+
this.executionMode = mode;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Update system prompt to reflect MCP changes (called after add/remove MCP)
|
|
77
|
+
*/
|
|
78
|
+
async updateSystemPrompt() {
|
|
79
|
+
const toolRegistry = getToolRegistry();
|
|
80
|
+
const promptGenerator = new SystemPromptGenerator(toolRegistry, this.executionMode);
|
|
81
|
+
// Use the current agent's original system prompt as base
|
|
82
|
+
const baseSystemPrompt = this.currentAgent?.systemPrompt || 'You are xAgent, an AI-powered CLI tool.';
|
|
83
|
+
const newSystemPrompt = await promptGenerator.generateEnhancedSystemPrompt(baseSystemPrompt);
|
|
84
|
+
// Replace old system prompt with new one
|
|
85
|
+
this.conversation = this.conversation.filter(msg => msg.role !== 'system');
|
|
86
|
+
this.conversation.unshift({
|
|
87
|
+
role: 'system',
|
|
88
|
+
content: newSystemPrompt,
|
|
89
|
+
timestamp: Date.now()
|
|
90
|
+
});
|
|
91
|
+
// Sync to slashCommandHandler
|
|
92
|
+
this.slashCommandHandler.setConversationHistory(this.conversation);
|
|
93
|
+
}
|
|
94
|
+
setAgent(agent) {
|
|
95
|
+
this.currentAgent = agent;
|
|
96
|
+
}
|
|
97
|
+
async start() {
|
|
98
|
+
const separator = icons.separator.repeat(60);
|
|
99
|
+
console.log('');
|
|
100
|
+
console.log(colors.gradient('╔════════════════════════════════════════════════════════════╗'));
|
|
101
|
+
console.log(colors.gradient('║') + ' '.repeat(56) + colors.gradient('║'));
|
|
102
|
+
console.log(' '.repeat(12) + colors.gradient('🤖 XAGENT CLI') + ' '.repeat(37) + colors.gradient('║'));
|
|
103
|
+
console.log(' '.repeat(14) + colors.textMuted('v1.0.0') + ' '.repeat(40) + colors.gradient('║'));
|
|
104
|
+
console.log(colors.gradient('║') + ' '.repeat(56) + colors.gradient('║'));
|
|
105
|
+
console.log(colors.gradient('╚════════════════════════════════════════════════════════════╝'));
|
|
106
|
+
console.log(colors.textMuted(' AI-powered command-line assistant'));
|
|
107
|
+
console.log('');
|
|
108
|
+
await this.initialize();
|
|
109
|
+
this.showWelcomeMessage();
|
|
110
|
+
// Track if an operation is in progress
|
|
111
|
+
this._isOperationInProgress = false;
|
|
112
|
+
// Listen for ESC cancellation - only cancel operations, don't exit the program
|
|
113
|
+
const cancelHandler = () => {
|
|
114
|
+
if (this._isOperationInProgress) {
|
|
115
|
+
// An operation is running, let it be cancelled
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// No operation running, ignore ESC or show a message
|
|
119
|
+
};
|
|
120
|
+
this.cancellationManager.on('cancelled', cancelHandler);
|
|
121
|
+
this.promptLoop();
|
|
122
|
+
// Keep the promise pending until shutdown
|
|
123
|
+
return new Promise((resolve) => {
|
|
124
|
+
this._shutdownResolver = resolve;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async initialize() {
|
|
128
|
+
try {
|
|
129
|
+
const spinner = ora({
|
|
130
|
+
text: colors.textMuted('Initializing XAGENT CLI...'),
|
|
131
|
+
spinner: 'dots',
|
|
132
|
+
color: 'cyan'
|
|
133
|
+
}).start();
|
|
134
|
+
await this.configManager.load();
|
|
135
|
+
let authConfig = this.configManager.getAuthConfig();
|
|
136
|
+
// If there's an API key, validate it with the backend
|
|
137
|
+
if (authConfig.apiKey) {
|
|
138
|
+
spinner.text = colors.textMuted('Validating authentication...');
|
|
139
|
+
const baseUrl = authConfig.xagentApiBaseUrl || 'http://xagent-colife.net:3000';
|
|
140
|
+
let isValid = await this.validateToken(baseUrl, authConfig.apiKey);
|
|
141
|
+
// Try refresh token if validation failed
|
|
142
|
+
if (!isValid && authConfig.refreshToken) {
|
|
143
|
+
console.log(colors.info(`[DEBUG] Token expired, trying to refresh...`));
|
|
144
|
+
spinner.text = colors.textMuted('Refreshing authentication...');
|
|
145
|
+
const newToken = await this.refreshToken(baseUrl, authConfig.refreshToken);
|
|
146
|
+
if (newToken) {
|
|
147
|
+
// Save new token
|
|
148
|
+
await this.configManager.set('apiKey', newToken);
|
|
149
|
+
authConfig.apiKey = newToken;
|
|
150
|
+
isValid = true;
|
|
151
|
+
console.log(colors.success(`[DEBUG] Token refreshed successfully!`));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!isValid) {
|
|
155
|
+
spinner.stop();
|
|
156
|
+
console.log('');
|
|
157
|
+
console.log(colors.warning('⚠️ Authentication expired or invalid'));
|
|
158
|
+
console.log(colors.info('Please log in again to continue.'));
|
|
159
|
+
console.log('');
|
|
160
|
+
// Clear invalid credentials
|
|
161
|
+
await this.configManager.set('apiKey', '');
|
|
162
|
+
await this.configManager.set('refreshToken', '');
|
|
163
|
+
await this.configManager.set('selectedAuthType', AuthType.OAUTH_XAGENT);
|
|
164
|
+
await this.setupAuthentication();
|
|
165
|
+
authConfig = this.configManager.getAuthConfig();
|
|
166
|
+
// Recreate readline interface after inquirer
|
|
167
|
+
this.rl.close();
|
|
168
|
+
this.rl = readline.createInterface({
|
|
169
|
+
input: process.stdin,
|
|
170
|
+
output: process.stdout
|
|
171
|
+
});
|
|
172
|
+
this.rl.on('close', () => {
|
|
173
|
+
console.error('DEBUG: readline interface closed');
|
|
174
|
+
});
|
|
175
|
+
spinner.start();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
spinner.stop();
|
|
180
|
+
await this.setupAuthentication();
|
|
181
|
+
authConfig = this.configManager.getAuthConfig();
|
|
182
|
+
// Recreate readline interface after inquirer
|
|
183
|
+
this.rl.close();
|
|
184
|
+
this.rl = readline.createInterface({
|
|
185
|
+
input: process.stdin,
|
|
186
|
+
output: process.stdout
|
|
187
|
+
});
|
|
188
|
+
this.rl.on('close', () => {
|
|
189
|
+
console.error('DEBUG: readline interface closed');
|
|
190
|
+
});
|
|
191
|
+
spinner.start();
|
|
192
|
+
}
|
|
193
|
+
this.aiClient = new AIClient(authConfig);
|
|
194
|
+
this.contextCompressor.setAIClient(this.aiClient);
|
|
195
|
+
this.executionMode = this.configManager.getApprovalMode() || this.configManager.getExecutionMode();
|
|
196
|
+
await this.agentManager.loadAgents();
|
|
197
|
+
await this.memoryManager.loadMemory();
|
|
198
|
+
await this.conversationManager.initialize();
|
|
199
|
+
await this.sessionManager.initialize();
|
|
200
|
+
// Create a new conversation and session for this interactive session
|
|
201
|
+
const conversation = await this.conversationManager.createConversation();
|
|
202
|
+
await this.sessionManager.createSession(conversation.id, this.currentAgent?.name || 'general-purpose', this.executionMode);
|
|
203
|
+
// 同步对话历史到 slashCommandHandler
|
|
204
|
+
this.slashCommandHandler.setConversationHistory(this.conversation);
|
|
205
|
+
const mcpServers = this.configManager.getMcpServers();
|
|
206
|
+
console.log(`📋 Loading ${Object.keys(mcpServers).length} MCP servers from config`);
|
|
207
|
+
Object.entries(mcpServers).forEach(([name, config]) => {
|
|
208
|
+
console.log(`📝 Registering MCP server: ${name} (${config.transport})`);
|
|
209
|
+
this.mcpManager.registerServer(name, config);
|
|
210
|
+
});
|
|
211
|
+
// Eagerly connect to MCP servers to get tool definitions
|
|
212
|
+
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
213
|
+
try {
|
|
214
|
+
console.log(`${colors.info(`${icons.brain} Connecting to ${Object.keys(mcpServers).length} MCP server(s)...`)}`);
|
|
215
|
+
await this.mcpManager.connectAllServers();
|
|
216
|
+
const connectedCount = Array.from(this.mcpManager.getAllServers()).filter((s) => s.isServerConnected()).length;
|
|
217
|
+
const mcpTools = this.mcpManager.getToolDefinitions();
|
|
218
|
+
console.log(`${colors.success(`✓ ${connectedCount}/${Object.keys(mcpServers).length} MCP server(s) connected (${mcpTools.length} tools available)`)}`);
|
|
219
|
+
// Register MCP tools with the tool registry (hide MCP origin from LLM)
|
|
220
|
+
const toolRegistry = getToolRegistry();
|
|
221
|
+
const allMcpTools = this.mcpManager.getAllTools();
|
|
222
|
+
toolRegistry.registerMCPTools(allMcpTools);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
console.log(`${colors.warning(`⚠ MCP connection failed: ${error.message}`)}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const checkpointingConfig = this.configManager.getCheckpointingConfig();
|
|
229
|
+
if (checkpointingConfig.enabled) {
|
|
230
|
+
this.checkpointManager = getCheckpointManager(process.cwd(), checkpointingConfig.enabled, checkpointingConfig.maxCheckpoints);
|
|
231
|
+
await this.checkpointManager.initialize();
|
|
232
|
+
}
|
|
233
|
+
this.currentAgent = this.agentManager.getAgent('general-purpose');
|
|
234
|
+
spinner.succeed(colors.success('Initialization complete'));
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
const spinner = ora({ text: '', spinner: 'dots', color: 'red' }).start();
|
|
238
|
+
spinner.fail(colors.error(`Initialization failed: ${error.message}`));
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Validate token with the backend
|
|
244
|
+
* Returns true if token is valid, false otherwise
|
|
245
|
+
*/
|
|
246
|
+
async validateToken(baseUrl, apiKey) {
|
|
247
|
+
try {
|
|
248
|
+
// For OAuth XAGENT auth, use /api/auth/me endpoint
|
|
249
|
+
const url = `${baseUrl}/api/auth/me`;
|
|
250
|
+
console.log(colors.info(`[DEBUG] Validating token with: ${url}`));
|
|
251
|
+
const response = await fetch(url, {
|
|
252
|
+
method: 'GET',
|
|
253
|
+
headers: {
|
|
254
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
255
|
+
'Content-Type': 'application/json'
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
console.log(colors.info(`[DEBUG] Response status: ${response.status}`));
|
|
259
|
+
return response.ok;
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
console.log(colors.warning(`[DEBUG] Network error: ${error}`));
|
|
263
|
+
// Network error - could be server down, consider token invalid
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
async refreshToken(baseUrl, refreshToken) {
|
|
268
|
+
try {
|
|
269
|
+
const url = `${baseUrl}/api/auth/refresh`;
|
|
270
|
+
console.log(colors.info(`[DEBUG] Refreshing token with: ${url}`));
|
|
271
|
+
const response = await fetch(url, {
|
|
272
|
+
method: 'POST',
|
|
273
|
+
headers: {
|
|
274
|
+
'Content-Type': 'application/json'
|
|
275
|
+
},
|
|
276
|
+
body: JSON.stringify({ refreshToken })
|
|
277
|
+
});
|
|
278
|
+
if (response.ok) {
|
|
279
|
+
const data = await response.json();
|
|
280
|
+
console.log(colors.success(`[DEBUG] Token refreshed successfully`));
|
|
281
|
+
return data.token || null;
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
console.log(colors.warning(`[DEBUG] Token refresh failed: ${response.status}`));
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
console.log(colors.warning(`[DEBUG] Token refresh error: ${error}`));
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
async setupAuthentication() {
|
|
294
|
+
const separator = icons.separator.repeat(40);
|
|
295
|
+
console.log('');
|
|
296
|
+
console.log(colors.primaryBright(`${icons.lock} Setup Authentication`));
|
|
297
|
+
console.log(colors.border(separator));
|
|
298
|
+
console.log('');
|
|
299
|
+
const authType = await selectAuthType();
|
|
300
|
+
this.configManager.set('selectedAuthType', authType);
|
|
301
|
+
const authService = new AuthService({
|
|
302
|
+
type: authType,
|
|
303
|
+
apiKey: '',
|
|
304
|
+
baseUrl: '',
|
|
305
|
+
modelName: ''
|
|
306
|
+
});
|
|
307
|
+
const success = await authService.authenticate();
|
|
308
|
+
if (!success) {
|
|
309
|
+
console.log('');
|
|
310
|
+
console.log(colors.error('Authentication failed. Exiting...'));
|
|
311
|
+
console.log('');
|
|
312
|
+
process.exit(1);
|
|
313
|
+
}
|
|
314
|
+
const authConfig = authService.getAuthConfig();
|
|
315
|
+
// VLM configuration is optional - skip for now, can be configured later with /vlm command
|
|
316
|
+
console.log('');
|
|
317
|
+
console.log(colors.info(`${icons.info} VLM configuration is optional.`));
|
|
318
|
+
console.log(colors.info(`You can configure it later using the /vlm command if needed.`));
|
|
319
|
+
console.log('');
|
|
320
|
+
// Save LLM config only, skip VLM for now
|
|
321
|
+
await this.configManager.setAuthConfig(authConfig);
|
|
322
|
+
}
|
|
323
|
+
showWelcomeMessage() {
|
|
324
|
+
const language = this.configManager.getLanguage();
|
|
325
|
+
const separator = icons.separator.repeat(40);
|
|
326
|
+
console.log('');
|
|
327
|
+
console.log(colors.border(separator));
|
|
328
|
+
if (language === 'zh') {
|
|
329
|
+
console.log(colors.primaryBright(`${icons.sparkles} Welcome to XAGENT CLI!`));
|
|
330
|
+
console.log(colors.textMuted('Type /help to see available commands'));
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
console.log(colors.primaryBright(`${icons.sparkles} Welcome to XAGENT CLI!`));
|
|
334
|
+
console.log(colors.textMuted('Type /help to see available commands'));
|
|
335
|
+
}
|
|
336
|
+
console.log(colors.border(separator));
|
|
337
|
+
console.log('');
|
|
338
|
+
this.showExecutionMode();
|
|
339
|
+
}
|
|
340
|
+
showExecutionMode() {
|
|
341
|
+
const modeConfig = {
|
|
342
|
+
[ExecutionMode.YOLO]: {
|
|
343
|
+
color: colors.error,
|
|
344
|
+
icon: icons.fire,
|
|
345
|
+
description: 'Execute commands without confirmation'
|
|
346
|
+
},
|
|
347
|
+
[ExecutionMode.ACCEPT_EDITS]: {
|
|
348
|
+
color: colors.warning,
|
|
349
|
+
icon: icons.check,
|
|
350
|
+
description: 'Accept all edits automatically'
|
|
351
|
+
},
|
|
352
|
+
[ExecutionMode.PLAN]: {
|
|
353
|
+
color: colors.info,
|
|
354
|
+
icon: icons.brain,
|
|
355
|
+
description: 'Plan before executing'
|
|
356
|
+
},
|
|
357
|
+
[ExecutionMode.DEFAULT]: {
|
|
358
|
+
color: colors.success,
|
|
359
|
+
icon: icons.bolt,
|
|
360
|
+
description: 'Safe execution with confirmations'
|
|
361
|
+
},
|
|
362
|
+
[ExecutionMode.SMART]: {
|
|
363
|
+
color: colors.primaryBright,
|
|
364
|
+
icon: icons.sparkles,
|
|
365
|
+
description: 'Smart approval with intelligent security checks'
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
const config = modeConfig[this.executionMode];
|
|
369
|
+
const modeName = this.executionMode;
|
|
370
|
+
console.log(colors.textMuted(`${icons.info} Current Mode:`));
|
|
371
|
+
console.log(` ${config.color(config.icon)} ${styleHelpers.text.bold(config.color(modeName))}`);
|
|
372
|
+
console.log(` ${colors.textDim(` ${config.description}`)}`);
|
|
373
|
+
console.log('');
|
|
374
|
+
}
|
|
375
|
+
async promptLoop() {
|
|
376
|
+
// Check if we're shutting down
|
|
377
|
+
if (this._isShuttingDown) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
// Recreate readline interface
|
|
381
|
+
if (this.rl) {
|
|
382
|
+
this.rl.close();
|
|
383
|
+
}
|
|
384
|
+
// Enable raw mode BEFORE emitKeypressEvents for better ESC detection
|
|
385
|
+
if (process.stdin.isTTY) {
|
|
386
|
+
process.stdin.setRawMode(true);
|
|
387
|
+
}
|
|
388
|
+
process.stdin.resume();
|
|
389
|
+
readline.emitKeypressEvents(process.stdin);
|
|
390
|
+
this.rl = readline.createInterface({
|
|
391
|
+
input: process.stdin,
|
|
392
|
+
output: process.stdout
|
|
393
|
+
});
|
|
394
|
+
const prompt = `${colors.primaryBright('❯')} `;
|
|
395
|
+
this.rl.question(prompt, async (input) => {
|
|
396
|
+
if (this._isShuttingDown) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
try {
|
|
400
|
+
await this.handleInput(input);
|
|
401
|
+
}
|
|
402
|
+
catch (err) {
|
|
403
|
+
console.log(colors.error(`Error: ${err.message}`));
|
|
404
|
+
}
|
|
405
|
+
this.promptLoop();
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
async handleInput(input) {
|
|
409
|
+
const trimmedInput = input.trim();
|
|
410
|
+
if (!trimmedInput) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
if (trimmedInput.startsWith('/')) {
|
|
414
|
+
const handled = await this.slashCommandHandler.handleCommand(trimmedInput);
|
|
415
|
+
if (handled) {
|
|
416
|
+
this.executionMode = this.configManager.getApprovalMode() || this.configManager.getExecutionMode();
|
|
417
|
+
// 同步对话历史到 slashCommandHandler
|
|
418
|
+
this.slashCommandHandler.setConversationHistory(this.conversation);
|
|
419
|
+
}
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (trimmedInput.startsWith('$')) {
|
|
423
|
+
await this.handleSubAgentCommand(trimmedInput);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
await this.processUserMessage(trimmedInput);
|
|
427
|
+
}
|
|
428
|
+
async handleSubAgentCommand(input) {
|
|
429
|
+
const [agentType, ...taskParts] = input.slice(1).split(' ');
|
|
430
|
+
const task = taskParts.join(' ');
|
|
431
|
+
const agent = this.agentManager.getAgent(agentType);
|
|
432
|
+
if (!agent) {
|
|
433
|
+
console.log('');
|
|
434
|
+
console.log(colors.warning(`Agent not found: ${agentType}`));
|
|
435
|
+
console.log(colors.textMuted('Use /agents list to see available agents'));
|
|
436
|
+
console.log('');
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
console.log('');
|
|
440
|
+
console.log(colors.primaryBright(`${icons.robot} Using agent: ${agent.name || agent.agentType}`));
|
|
441
|
+
console.log(colors.border(icons.separator.repeat(40)));
|
|
442
|
+
console.log('');
|
|
443
|
+
this.currentAgent = agent;
|
|
444
|
+
await this.processUserMessage(task, agent);
|
|
445
|
+
}
|
|
446
|
+
async processUserMessage(message, agent) {
|
|
447
|
+
const inputs = parseInput(message);
|
|
448
|
+
const textInput = inputs.find(i => i.type === 'text');
|
|
449
|
+
const fileInputs = inputs.filter(i => i.type === 'file');
|
|
450
|
+
const commandInput = inputs.find(i => i.type === 'command');
|
|
451
|
+
if (commandInput) {
|
|
452
|
+
await this.executeShellCommand(commandInput.content);
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
let userContent = textInput?.content || '';
|
|
456
|
+
if (fileInputs.length > 0) {
|
|
457
|
+
const toolRegistry = getToolRegistry();
|
|
458
|
+
for (const fileInput of fileInputs) {
|
|
459
|
+
try {
|
|
460
|
+
const content = await toolRegistry.execute('Read', { filePath: fileInput.content }, this.executionMode);
|
|
461
|
+
userContent += `\n\n--- File: ${fileInput.content} ---\n${content}`;
|
|
462
|
+
}
|
|
463
|
+
catch (error) {
|
|
464
|
+
console.log(chalk.yellow(`Warning: Failed to read file ${fileInput.content}: ${error.message}`));
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
// Record input to session manager
|
|
469
|
+
const sessionInput = {
|
|
470
|
+
type: 'text',
|
|
471
|
+
content: userContent,
|
|
472
|
+
rawInput: message,
|
|
473
|
+
timestamp: Date.now()
|
|
474
|
+
};
|
|
475
|
+
await this.sessionManager.addInput(sessionInput);
|
|
476
|
+
// Calculate thinking tokens based on config and user input
|
|
477
|
+
const thinkingConfig = this.configManager.getThinkingConfig();
|
|
478
|
+
let thinkingTokens = 0;
|
|
479
|
+
if (thinkingConfig.enabled) {
|
|
480
|
+
// If thinking mode is enabled, detect keywords and calculate tokens
|
|
481
|
+
const thinkingMode = detectThinkingKeywords(userContent);
|
|
482
|
+
thinkingTokens = getThinkingTokens(thinkingMode);
|
|
483
|
+
}
|
|
484
|
+
const userMessage = {
|
|
485
|
+
role: 'user',
|
|
486
|
+
content: userContent,
|
|
487
|
+
timestamp: Date.now()
|
|
488
|
+
};
|
|
489
|
+
// Save last user message for recovery after compression
|
|
490
|
+
const lastUserMessage = userMessage;
|
|
491
|
+
this.conversation.push(userMessage);
|
|
492
|
+
await this.conversationManager.addMessage(userMessage);
|
|
493
|
+
// 检查是否需要压缩上下文
|
|
494
|
+
await this.checkAndCompressContext(lastUserMessage);
|
|
495
|
+
await this.generateResponse(thinkingTokens);
|
|
496
|
+
}
|
|
497
|
+
displayThinkingContent(reasoningContent) {
|
|
498
|
+
const indent = this.getIndent();
|
|
499
|
+
const thinkingConfig = this.configManager.getThinkingConfig();
|
|
500
|
+
const displayMode = thinkingConfig.displayMode || 'compact';
|
|
501
|
+
const separator = icons.separator.repeat(Math.min(60, process.stdout.columns || 80) - indent.length);
|
|
502
|
+
console.log('');
|
|
503
|
+
console.log(`${indent}${colors.border(separator)}`);
|
|
504
|
+
switch (displayMode) {
|
|
505
|
+
case 'full':
|
|
506
|
+
// Full display, using small font and gray color
|
|
507
|
+
console.log(`${indent}${colors.textDim(`${icons.brain} Thinking Process:`)}`);
|
|
508
|
+
console.log('');
|
|
509
|
+
console.log(`${indent}${colors.textDim(reasoningContent.replace(/^/gm, indent))}`);
|
|
510
|
+
break;
|
|
511
|
+
case 'compact':
|
|
512
|
+
// Compact display, truncate partial content
|
|
513
|
+
const maxLength = 500;
|
|
514
|
+
const truncatedContent = reasoningContent.length > maxLength
|
|
515
|
+
? reasoningContent.substring(0, maxLength) + '... (truncated)'
|
|
516
|
+
: reasoningContent;
|
|
517
|
+
console.log(`${indent}${colors.textDim(`${icons.brain} Thinking Process:`)}`);
|
|
518
|
+
console.log('');
|
|
519
|
+
console.log(`${indent}${colors.textDim(truncatedContent.replace(/^/gm, indent))}`);
|
|
520
|
+
console.log(`${indent}${colors.textDim(`[${reasoningContent.length} chars total]`)}`);
|
|
521
|
+
break;
|
|
522
|
+
case 'indicator':
|
|
523
|
+
// Show indicator only
|
|
524
|
+
console.log(`${indent}${colors.textDim(`${icons.brain} Thinking process completed`)}`);
|
|
525
|
+
console.log(`${indent}${colors.textDim(`[${reasoningContent.length} chars of reasoning]`)}`);
|
|
526
|
+
break;
|
|
527
|
+
default:
|
|
528
|
+
console.log(`${indent}${colors.textDim(`${icons.brain} Thinking:`)}`);
|
|
529
|
+
console.log('');
|
|
530
|
+
console.log(`${indent}${colors.textDim(reasoningContent.replace(/^/gm, indent))}`);
|
|
531
|
+
}
|
|
532
|
+
console.log(`${indent}${colors.border(separator)}`);
|
|
533
|
+
console.log('');
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* 检查并压缩对话上下文
|
|
537
|
+
*/
|
|
538
|
+
async checkAndCompressContext(lastUserMessage) {
|
|
539
|
+
const compressionConfig = this.configManager.getContextCompressionConfig();
|
|
540
|
+
if (!compressionConfig.enabled) {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
const { needsCompression, reason } = this.contextCompressor.needsCompression(this.conversation, compressionConfig);
|
|
544
|
+
if (needsCompression) {
|
|
545
|
+
const indent = this.getIndent();
|
|
546
|
+
console.log('');
|
|
547
|
+
console.log(`${indent}${colors.warning(`${icons.brain} Context compression triggered: ${reason}`)}`);
|
|
548
|
+
const toolRegistry = getToolRegistry();
|
|
549
|
+
const baseSystemPrompt = this.currentAgent?.systemPrompt || 'You are a helpful AI assistant.';
|
|
550
|
+
const systemPromptGenerator = new SystemPromptGenerator(toolRegistry, this.executionMode);
|
|
551
|
+
const enhancedSystemPrompt = await systemPromptGenerator.generateEnhancedSystemPrompt(baseSystemPrompt);
|
|
552
|
+
const result = await this.contextCompressor.compressContext(this.conversation, enhancedSystemPrompt, compressionConfig);
|
|
553
|
+
if (result.wasCompressed) {
|
|
554
|
+
this.conversation = result.compressedMessages;
|
|
555
|
+
// console.log(`${indent}${colors.success(`✓ Compressed ${result.originalMessageCount} messages to ${result.compressedMessageCount} messages`)}`);
|
|
556
|
+
console.log(`${indent}${colors.textMuted(`✓ Size: ${result.originalSize} → ${result.compressedSize} chars (${Math.round((1 - result.compressedSize / result.originalSize) * 100)}% reduction)`)}`);
|
|
557
|
+
// 显示压缩后的摘要内容
|
|
558
|
+
const summaryMessage = result.compressedMessages.find(m => m.role === 'assistant');
|
|
559
|
+
if (summaryMessage && summaryMessage.content) {
|
|
560
|
+
const maxPreviewLength = 800;
|
|
561
|
+
let summaryContent = summaryMessage.content;
|
|
562
|
+
const isTruncated = summaryContent.length > maxPreviewLength;
|
|
563
|
+
if (isTruncated) {
|
|
564
|
+
summaryContent = summaryContent.substring(0, maxPreviewLength) + '\n...';
|
|
565
|
+
}
|
|
566
|
+
console.log('');
|
|
567
|
+
console.log(`${indent}${theme.predefinedStyles.title(`${icons.sparkles} Conversation Summary`)}`);
|
|
568
|
+
const separator = icons.separator.repeat(Math.min(60, process.stdout.columns || 80) - indent.length * 2);
|
|
569
|
+
console.log(`${indent}${colors.border(separator)}`);
|
|
570
|
+
const renderedSummary = renderMarkdown(summaryContent, (process.stdout.columns || 80) - indent.length * 4);
|
|
571
|
+
console.log(`${indent}${theme.predefinedStyles.dim(renderedSummary).replace(/^/gm, indent)}`);
|
|
572
|
+
if (isTruncated) {
|
|
573
|
+
console.log(`${indent}${colors.textMuted(`(... ${summaryMessage.content.length - maxPreviewLength} more chars hidden)`)}`);
|
|
574
|
+
}
|
|
575
|
+
console.log(`${indent}${colors.border(separator)}`);
|
|
576
|
+
}
|
|
577
|
+
// 压缩后恢复用户消息,确保 API 调用时有 user 消息
|
|
578
|
+
if (lastUserMessage) {
|
|
579
|
+
this.conversation.push(lastUserMessage);
|
|
580
|
+
}
|
|
581
|
+
// 同步压缩后的对话历史到 slashCommandHandler
|
|
582
|
+
this.slashCommandHandler.setConversationHistory(this.conversation);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
async executeShellCommand(command) {
|
|
587
|
+
const indent = this.getIndent();
|
|
588
|
+
console.log('');
|
|
589
|
+
console.log(`${indent}${colors.textMuted(`${icons.code} Executing:`)}`);
|
|
590
|
+
console.log(`${indent}${colors.codeText(` $ ${command}`)}`);
|
|
591
|
+
console.log(`${indent}${colors.border(icons.separator.repeat(Math.min(60, process.stdout.columns || 80) - indent.length))}`);
|
|
592
|
+
console.log('');
|
|
593
|
+
const toolRegistry = getToolRegistry();
|
|
594
|
+
try {
|
|
595
|
+
const result = await toolRegistry.execute('Bash', { command }, this.executionMode);
|
|
596
|
+
if (result.stdout) {
|
|
597
|
+
console.log(`${indent}${result.stdout.replace(/^/gm, indent)}`);
|
|
598
|
+
}
|
|
599
|
+
if (result.stderr) {
|
|
600
|
+
console.log(`${indent}${colors.warning(result.stderr.replace(/^/gm, indent))}`);
|
|
601
|
+
}
|
|
602
|
+
const toolCall = {
|
|
603
|
+
tool: 'Bash',
|
|
604
|
+
params: { command },
|
|
605
|
+
result,
|
|
606
|
+
timestamp: Date.now()
|
|
607
|
+
};
|
|
608
|
+
this.toolCalls.push(toolCall);
|
|
609
|
+
// Record command execution to session manager
|
|
610
|
+
await this.sessionManager.addInput({
|
|
611
|
+
type: 'command',
|
|
612
|
+
content: command,
|
|
613
|
+
rawInput: command,
|
|
614
|
+
timestamp: Date.now()
|
|
615
|
+
});
|
|
616
|
+
await this.sessionManager.addOutput({
|
|
617
|
+
role: 'tool',
|
|
618
|
+
content: JSON.stringify(result),
|
|
619
|
+
toolName: 'Bash',
|
|
620
|
+
toolParams: { command },
|
|
621
|
+
toolResult: result,
|
|
622
|
+
timestamp: Date.now()
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
catch (error) {
|
|
626
|
+
console.log(`${indent}${colors.error(`Command execution failed: ${error.message}`)}`);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
async generateResponse(thinkingTokens = 0) {
|
|
630
|
+
if (!this.aiClient) {
|
|
631
|
+
console.log(colors.error('AI client not initialized'));
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
// Mark that an operation is in progress
|
|
635
|
+
this._isOperationInProgress = true;
|
|
636
|
+
const indent = this.getIndent();
|
|
637
|
+
const thinkingText = colors.textMuted(`Thinking... (Press ESC to cancel)`);
|
|
638
|
+
const icon = colors.primary(icons.brain);
|
|
639
|
+
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
640
|
+
let frameIndex = 0;
|
|
641
|
+
// Custom spinner: only icon rotates, text stays static
|
|
642
|
+
const spinnerInterval = setInterval(() => {
|
|
643
|
+
process.stdout.write(`\r${colors.primary(frames[frameIndex])} ${icon} ${thinkingText}`);
|
|
644
|
+
frameIndex = (frameIndex + 1) % frames.length;
|
|
645
|
+
}, 120);
|
|
646
|
+
try {
|
|
647
|
+
const memory = await this.memoryManager.loadMemory();
|
|
648
|
+
const toolRegistry = getToolRegistry();
|
|
649
|
+
const allowedToolNames = this.currentAgent
|
|
650
|
+
? this.agentManager.getAvailableToolsForAgent(this.currentAgent, this.executionMode)
|
|
651
|
+
: [];
|
|
652
|
+
// MCP servers are already connected during initialization (eager mode)
|
|
653
|
+
const allLocalToolDefinitions = toolRegistry.getToolDefinitions();
|
|
654
|
+
const mcpToolDefinitions = this.mcpManager.getToolDefinitions();
|
|
655
|
+
// Merge local tools and MCP tools
|
|
656
|
+
const allToolDefinitions = [...allLocalToolDefinitions, ...mcpToolDefinitions];
|
|
657
|
+
const availableTools = this.executionMode !== ExecutionMode.DEFAULT && allowedToolNames.length > 0
|
|
658
|
+
? allToolDefinitions.filter((tool) => allowedToolNames.includes(tool.function.name))
|
|
659
|
+
: allToolDefinitions;
|
|
660
|
+
const baseSystemPrompt = this.currentAgent?.systemPrompt;
|
|
661
|
+
const systemPromptGenerator = new SystemPromptGenerator(toolRegistry, this.executionMode);
|
|
662
|
+
const enhancedSystemPrompt = await systemPromptGenerator.generateEnhancedSystemPrompt(baseSystemPrompt);
|
|
663
|
+
const messages = [
|
|
664
|
+
{ role: 'system', content: `${enhancedSystemPrompt}\n\n${memory}` },
|
|
665
|
+
...this.conversation.map(msg => ({
|
|
666
|
+
role: msg.role,
|
|
667
|
+
content: msg.content
|
|
668
|
+
}))
|
|
669
|
+
];
|
|
670
|
+
// Debug: 打印完整的 prompt 信息
|
|
671
|
+
// const logger = new Logger({ minLevel: LogLevel.DEBUG });
|
|
672
|
+
// logger.debug('[DEBUG] 即将发送给 AI 的完整 Prompt:');
|
|
673
|
+
// console.log('\n' + '='.repeat(60));
|
|
674
|
+
// console.log('【SYSTEM PROMPT】');
|
|
675
|
+
// console.log('-'.repeat(60));
|
|
676
|
+
// console.log(messages[0]?.content || '(无)');
|
|
677
|
+
// console.log('='.repeat(60));
|
|
678
|
+
// console.log('【CONVERSATION】');
|
|
679
|
+
// console.log('-'.repeat(60));
|
|
680
|
+
// messages.slice(1).forEach((msg, idx) => {
|
|
681
|
+
// const contentStr = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);
|
|
682
|
+
// console.log(`[${idx + 1}] [${msg.role}]: ${contentStr.substring(0, 200)}${contentStr.length > 200 ? '...' : ''}`);
|
|
683
|
+
// });
|
|
684
|
+
// console.log('='.repeat(60));
|
|
685
|
+
// console.log(`【AVAILABLE TOOLS】: ${availableTools.length} 个工具`);
|
|
686
|
+
// availableTools.forEach((tool: any) => {
|
|
687
|
+
// console.log(` - ${tool.function.name}`);
|
|
688
|
+
// }); // console.log('='.repeat(60) + '\n');
|
|
689
|
+
// Debug: 打印AI输入信息 (已移至 ai-client.ts)
|
|
690
|
+
// if (this.configManager.get('showAIDebugInfo')) {
|
|
691
|
+
// this.displayAIDebugInfo('INPUT', messages, availableTools);
|
|
692
|
+
// }
|
|
693
|
+
const operationId = `ai-response-${Date.now()}`;
|
|
694
|
+
const responsePromise = this.aiClient.chatCompletion(messages, {
|
|
695
|
+
tools: availableTools,
|
|
696
|
+
toolChoice: availableTools.length > 0 ? 'auto' : 'none',
|
|
697
|
+
thinkingTokens
|
|
698
|
+
});
|
|
699
|
+
const response = await this.cancellationManager.withCancellation(responsePromise, operationId);
|
|
700
|
+
clearInterval(spinnerInterval);
|
|
701
|
+
process.stdout.write('\r' + ' '.repeat(process.stdout.columns || 80) + '\r'); // Clear spinner line
|
|
702
|
+
const assistantMessage = response.choices[0].message;
|
|
703
|
+
// Debug: 打印AI输出信息 (已移至 ai-client.ts)
|
|
704
|
+
// if (this.configManager.get('showAIDebugInfo')) {
|
|
705
|
+
// this.displayAIDebugInfo('OUTPUT', response, assistantMessage);
|
|
706
|
+
// }
|
|
707
|
+
const content = typeof assistantMessage.content === 'string'
|
|
708
|
+
? assistantMessage.content
|
|
709
|
+
: '';
|
|
710
|
+
const reasoningContent = assistantMessage.reasoning_content || '';
|
|
711
|
+
// console.error('[SESSION DEBUG] assistantMessage:', JSON.stringify(assistantMessage).substring(0, 200));
|
|
712
|
+
// console.error('[SESSION DEBUG] content:', content);
|
|
713
|
+
// Display reasoning content if available and thinking mode is enabled
|
|
714
|
+
if (reasoningContent && this.configManager.getThinkingConfig().enabled) {
|
|
715
|
+
this.displayThinkingContent(reasoningContent);
|
|
716
|
+
}
|
|
717
|
+
console.log('');
|
|
718
|
+
console.log(`${indent}${colors.primaryBright(`${icons.robot} Assistant:`)}`);
|
|
719
|
+
console.log(`${indent}${colors.border(icons.separator.repeat(Math.min(60, process.stdout.columns || 80) - indent.length))}`);
|
|
720
|
+
console.log('');
|
|
721
|
+
const renderedContent = renderMarkdown(content, (process.stdout.columns || 80) - indent.length * 2);
|
|
722
|
+
console.log(`${indent}${renderedContent.replace(/^/gm, indent)}`);
|
|
723
|
+
console.log('');
|
|
724
|
+
this.conversation.push({
|
|
725
|
+
role: 'assistant',
|
|
726
|
+
content,
|
|
727
|
+
timestamp: Date.now(),
|
|
728
|
+
reasoningContent,
|
|
729
|
+
toolCalls: assistantMessage.tool_calls
|
|
730
|
+
});
|
|
731
|
+
// Record output to session manager
|
|
732
|
+
await this.sessionManager.addOutput({
|
|
733
|
+
role: 'assistant',
|
|
734
|
+
content,
|
|
735
|
+
timestamp: Date.now(),
|
|
736
|
+
reasoningContent,
|
|
737
|
+
toolCalls: assistantMessage.tool_calls
|
|
738
|
+
});
|
|
739
|
+
if (assistantMessage.tool_calls) {
|
|
740
|
+
await this.handleToolCalls(assistantMessage.tool_calls);
|
|
741
|
+
}
|
|
742
|
+
if (this.checkpointManager.isEnabled()) {
|
|
743
|
+
await this.checkpointManager.createCheckpoint(`Response generated at ${new Date().toLocaleString()}`, [...this.conversation], [...this.toolCalls]);
|
|
744
|
+
}
|
|
745
|
+
// Operation completed successfully, clear the flag
|
|
746
|
+
this._isOperationInProgress = false;
|
|
747
|
+
}
|
|
748
|
+
catch (error) {
|
|
749
|
+
clearInterval(spinnerInterval);
|
|
750
|
+
process.stdout.write('\r' + ' '.repeat(process.stdout.columns || 80) + '\r');
|
|
751
|
+
// Clear the operation flag
|
|
752
|
+
this._isOperationInProgress = false;
|
|
753
|
+
if (error.message === 'Operation cancelled by user') {
|
|
754
|
+
// Message is already logged by CancellationManager
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
console.log(colors.error(`Error: ${error.message}`));
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
async handleToolCalls(toolCalls) {
|
|
761
|
+
// Mark that tool execution is in progress
|
|
762
|
+
this._isOperationInProgress = true;
|
|
763
|
+
const toolRegistry = getToolRegistry();
|
|
764
|
+
const showToolDetails = this.configManager.get('showToolDetails') || false;
|
|
765
|
+
const indent = this.getIndent();
|
|
766
|
+
// Prepare all tool calls
|
|
767
|
+
const preparedToolCalls = toolCalls.map((toolCall, index) => {
|
|
768
|
+
const { name, arguments: params } = toolCall.function;
|
|
769
|
+
let parsedParams;
|
|
770
|
+
try {
|
|
771
|
+
parsedParams = typeof params === 'string' ? JSON.parse(params) : params;
|
|
772
|
+
}
|
|
773
|
+
catch (e) {
|
|
774
|
+
parsedParams = params;
|
|
775
|
+
}
|
|
776
|
+
return { name, params: parsedParams, index };
|
|
777
|
+
});
|
|
778
|
+
// Display all tool calls info
|
|
779
|
+
for (const { name, params } of preparedToolCalls) {
|
|
780
|
+
if (showToolDetails) {
|
|
781
|
+
console.log('');
|
|
782
|
+
console.log(`${indent}${colors.warning(`${icons.tool} Tool Call: ${name}`)}`);
|
|
783
|
+
console.log(`${indent}${colors.textDim(JSON.stringify(params, null, 2))}`);
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
const toolDescription = this.getToolDescription(name, params);
|
|
787
|
+
console.log('');
|
|
788
|
+
console.log(`${indent}${colors.textMuted(`${icons.loading} ${toolDescription}`)}`);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
// Execute all tools in parallel
|
|
792
|
+
const results = await toolRegistry.executeAll(preparedToolCalls.map(tc => ({ name: tc.name, params: tc.params })), this.executionMode);
|
|
793
|
+
// Process results and maintain order
|
|
794
|
+
for (const { tool, result, error } of results) {
|
|
795
|
+
const toolCall = preparedToolCalls.find(tc => tc.name === tool);
|
|
796
|
+
if (!toolCall)
|
|
797
|
+
continue;
|
|
798
|
+
const { params } = toolCall;
|
|
799
|
+
if (error) {
|
|
800
|
+
// Clear the operation flag
|
|
801
|
+
this._isOperationInProgress = false;
|
|
802
|
+
if (error === 'Operation cancelled by user') {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
console.log('');
|
|
806
|
+
console.log(`${indent}${colors.error(`${icons.cross} Tool Error: ${error}`)}`);
|
|
807
|
+
this.conversation.push({
|
|
808
|
+
role: 'tool',
|
|
809
|
+
content: JSON.stringify({ error }),
|
|
810
|
+
timestamp: Date.now()
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
else {
|
|
814
|
+
// Use correct indent for gui-subagent tasks
|
|
815
|
+
const isGuiSubagent = tool === 'task' && params?.subagent_type === 'gui-subagent';
|
|
816
|
+
const displayIndent = isGuiSubagent ? indent + ' ' : indent;
|
|
817
|
+
// Always show details for todo tools so users can see their task lists
|
|
818
|
+
const isTodoTool = tool === 'todo_write' || tool === 'todo_read';
|
|
819
|
+
if (isTodoTool) {
|
|
820
|
+
console.log('');
|
|
821
|
+
console.log(`${displayIndent}${colors.success(`${icons.check} Todo List:`)}`);
|
|
822
|
+
console.log(this.renderTodoList(result.todos || result.todos, displayIndent));
|
|
823
|
+
// Show summary if available
|
|
824
|
+
if (result.message) {
|
|
825
|
+
console.log(`${displayIndent}${colors.textDim(result.message)}`);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
else if (showToolDetails) {
|
|
829
|
+
console.log('');
|
|
830
|
+
console.log(`${displayIndent}${colors.success(`${icons.check} Tool Result:`)}`);
|
|
831
|
+
console.log(`${displayIndent}${colors.textDim(JSON.stringify(result, null, 2))}`);
|
|
832
|
+
}
|
|
833
|
+
else if (result.success === false) {
|
|
834
|
+
// GUI task or other tool failed
|
|
835
|
+
console.log(`${displayIndent}${colors.error(`${icons.cross} ${result.message || 'Failed'}`)}`);
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
console.log(`${displayIndent}${colors.success(`${icons.check} Completed`)}`);
|
|
839
|
+
}
|
|
840
|
+
const toolCallRecord = {
|
|
841
|
+
tool,
|
|
842
|
+
params,
|
|
843
|
+
result,
|
|
844
|
+
timestamp: Date.now()
|
|
845
|
+
};
|
|
846
|
+
this.toolCalls.push(toolCallRecord);
|
|
847
|
+
// Record tool output to session manager
|
|
848
|
+
await this.sessionManager.addOutput({
|
|
849
|
+
role: 'tool',
|
|
850
|
+
content: JSON.stringify(result),
|
|
851
|
+
toolName: tool,
|
|
852
|
+
toolParams: params,
|
|
853
|
+
toolResult: result,
|
|
854
|
+
timestamp: Date.now()
|
|
855
|
+
});
|
|
856
|
+
this.conversation.push({
|
|
857
|
+
role: 'tool',
|
|
858
|
+
content: JSON.stringify(result),
|
|
859
|
+
timestamp: Date.now()
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
// Logic: Only skip returning results to main agent when user explicitly cancelled (ESC)
|
|
864
|
+
// For all other cases (success, failure, errors), always return results for further processing
|
|
865
|
+
const guiSubagentFailed = preparedToolCalls.some(tc => tc.name === 'task' && tc.params?.subagent_type === 'gui-subagent');
|
|
866
|
+
const guiSubagentCancelled = preparedToolCalls.some(tc => tc.name === 'task' && tc.params?.subagent_type === 'gui-subagent' && results.some(r => r.tool === 'task' && r.result?.cancelled === true));
|
|
867
|
+
// If GUI agent was cancelled by user, don't continue generating response
|
|
868
|
+
// This avoids wasting API calls and tokens on cancelled tasks
|
|
869
|
+
if (guiSubagentCancelled) {
|
|
870
|
+
console.log('');
|
|
871
|
+
console.log(`${indent}${colors.textMuted('GUI task cancelled by user')}`);
|
|
872
|
+
this._isOperationInProgress = false;
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
// For all other cases (GUI success/failure, other tool errors), return results to main agent
|
|
876
|
+
// This allows main agent to decide how to handle failures (retry, fallback, user notification, etc.)
|
|
877
|
+
await this.generateResponse();
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Get user-friendly description for tool
|
|
881
|
+
*/
|
|
882
|
+
getToolDescription(toolName, params) {
|
|
883
|
+
const descriptions = {
|
|
884
|
+
'Read': (p) => `Read file: ${this.truncatePath(p.filePath)}`,
|
|
885
|
+
'Write': (p) => `Write file: ${this.truncatePath(p.filePath)}`,
|
|
886
|
+
'Grep': (p) => `Search text: "${p.pattern}"`,
|
|
887
|
+
'Bash': (p) => `Execute command: ${this.truncateCommand(p.command)}`,
|
|
888
|
+
'ListDirectory': (p) => `List directory: ${this.truncatePath(p.path || '.')}`,
|
|
889
|
+
'SearchCodebase': (p) => `Search files: ${p.pattern}`,
|
|
890
|
+
'DeleteFile': (p) => `Delete file: ${this.truncatePath(p.filePath)}`,
|
|
891
|
+
'CreateDirectory': (p) => `Create directory: ${this.truncatePath(p.dirPath)}`,
|
|
892
|
+
'replace': (p) => `Replace text: ${this.truncatePath(p.file_path)}`,
|
|
893
|
+
'web_search': (p) => `Web search: "${p.query}"`,
|
|
894
|
+
'todo_write': () => `Update todo list`,
|
|
895
|
+
'todo_read': () => `Read todo list`,
|
|
896
|
+
'task': (p) => `Launch subtask: ${p.description}`,
|
|
897
|
+
'ReadBashOutput': (p) => `Read task output: ${p.task_id}`,
|
|
898
|
+
'web_fetch': () => `Fetch web content`,
|
|
899
|
+
'ask_user_question': () => `Ask user`,
|
|
900
|
+
'save_memory': () => `Save memory`,
|
|
901
|
+
'exit_plan_mode': () => `Complete plan`,
|
|
902
|
+
'xml_escape': (p) => `XML escape: ${this.truncatePath(p.file_path)}`,
|
|
903
|
+
'image_read': (p) => `Read image: ${this.truncatePath(p.image_input)}`,
|
|
904
|
+
// 'Skill': (p) => `Execute skill: ${p.skill}`,
|
|
905
|
+
// 'ListSkills': () => `List available skills`,
|
|
906
|
+
// 'GetSkillDetails': (p) => `Get skill details: ${p.skill}`,
|
|
907
|
+
'InvokeSkill': (p) => `Invoke skill: ${p.skillId} - ${this.truncatePath(p.taskDescription || '', 40)}`
|
|
908
|
+
};
|
|
909
|
+
const getDescription = descriptions[toolName];
|
|
910
|
+
return getDescription ? getDescription(params) : `Execute tool: ${toolName}`;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Truncate path for display
|
|
914
|
+
*/
|
|
915
|
+
truncatePath(path, maxLength = 30) {
|
|
916
|
+
if (!path)
|
|
917
|
+
return '';
|
|
918
|
+
if (path.length <= maxLength)
|
|
919
|
+
return path;
|
|
920
|
+
return '...' + path.slice(-(maxLength - 3));
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Truncate command for display
|
|
924
|
+
*/
|
|
925
|
+
truncateCommand(command, maxLength = 40) {
|
|
926
|
+
if (!command)
|
|
927
|
+
return '';
|
|
928
|
+
if (command.length <= maxLength)
|
|
929
|
+
return command;
|
|
930
|
+
return command.slice(0, maxLength - 3) + '...';
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Render todo list in a user-friendly format
|
|
934
|
+
*/
|
|
935
|
+
renderTodoList(todos, indent = '') {
|
|
936
|
+
if (!todos || todos.length === 0) {
|
|
937
|
+
return `${indent}${colors.textMuted('No tasks')}`;
|
|
938
|
+
}
|
|
939
|
+
const statusConfig = {
|
|
940
|
+
'pending': { icon: icons.circle, color: colors.textMuted, label: 'Pending' },
|
|
941
|
+
'in_progress': { icon: icons.loading, color: colors.warning, label: 'In Progress' },
|
|
942
|
+
'completed': { icon: icons.success, color: colors.success, label: 'Completed' },
|
|
943
|
+
'failed': { icon: icons.error, color: colors.error, label: 'Failed' }
|
|
944
|
+
};
|
|
945
|
+
const lines = [];
|
|
946
|
+
for (const todo of todos) {
|
|
947
|
+
const config = statusConfig[todo.status] || statusConfig['pending'];
|
|
948
|
+
const statusPrefix = `${config.color(config.icon)} ${config.color(config.label)}:`;
|
|
949
|
+
lines.push(`${indent} ${statusPrefix} ${colors.text(todo.task)}`);
|
|
950
|
+
}
|
|
951
|
+
return lines.join('\n');
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Display AI debug information (input or output)
|
|
955
|
+
*/
|
|
956
|
+
// AI 调试信息已移至 ai-client.ts 实现
|
|
957
|
+
// private displayAIDebugInfo(type: 'INPUT' | 'OUTPUT', data: any, extra?: any): void {
|
|
958
|
+
// const indent = this.getIndent();
|
|
959
|
+
// const boxChar = {
|
|
960
|
+
// topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',
|
|
961
|
+
// horizontal: '═', vertical: '║'
|
|
962
|
+
// };
|
|
963
|
+
//
|
|
964
|
+
// console.log('\n' + colors.border(
|
|
965
|
+
// `${boxChar.topLeft}${boxChar.horizontal.repeat(58)}${boxChar.topRight}`
|
|
966
|
+
// ));
|
|
967
|
+
// console.log(colors.border(`${boxChar.vertical}`) + ' ' +
|
|
968
|
+
// colors.primaryBright(type === 'INPUT' ? '🤖 AI INPUT DEBUG' : '📤 AI OUTPUT DEBUG') +
|
|
969
|
+
// ' '.repeat(36) + colors.border(boxChar.vertical));
|
|
970
|
+
// console.log(colors.border(
|
|
971
|
+
// `${boxChar.vertical}${boxChar.horizontal.repeat(58)}${boxChar.vertical}`
|
|
972
|
+
// ));
|
|
973
|
+
//
|
|
974
|
+
// if (type === 'INPUT') {
|
|
975
|
+
// const messages = data as any[];
|
|
976
|
+
// const tools = extra as any[];
|
|
977
|
+
//
|
|
978
|
+
// // System prompt
|
|
979
|
+
// const systemMsg = messages.find((m: any) => m.role === 'system');
|
|
980
|
+
// console.log(colors.border(`${boxChar.vertical}`) + ' 🟫 SYSTEM: ' +
|
|
981
|
+
// colors.textMuted(systemMsg?.content?.toString().substring(0, 50) || '(无)') + ' '.repeat(3) + colors.border(boxChar.vertical));
|
|
982
|
+
//
|
|
983
|
+
// // Messages count
|
|
984
|
+
// console.log(colors.border(`${boxChar.vertical}`) + ' 💬 MESSAGES: ' +
|
|
985
|
+
// colors.text(messages.length.toString()) + ' 条' + ' '.repeat(40) + colors.border(boxChar.vertical));
|
|
986
|
+
//
|
|
987
|
+
// // Tools count
|
|
988
|
+
// console.log(colors.border(`${boxChar.vertical}`) + ' 🔧 TOOLS: ' +
|
|
989
|
+
// colors.text((tools?.length || 0).toString()) + ' 个' + ' '.repeat(43) + colors.border(boxChar.vertical));
|
|
990
|
+
//
|
|
991
|
+
// // Show last 2 messages
|
|
992
|
+
// const recentMessages = messages.slice(-2);
|
|
993
|
+
// for (const msg of recentMessages) {
|
|
994
|
+
// const roleLabel: Record<string, string> = { user: '👤 USER', assistant: '🤖 ASSISTANT', tool: '🔧 TOOL' };
|
|
995
|
+
// const label = roleLabel[msg.role] || msg.role;
|
|
996
|
+
// const contentStr = typeof msg.content === 'string'
|
|
997
|
+
// ? msg.content.substring(0, 100)
|
|
998
|
+
// : JSON.stringify(msg.content).substring(0, 100);
|
|
999
|
+
// console.log(colors.border(`${boxChar.vertical}`) + ` ${label}: ` +
|
|
1000
|
+
// colors.textDim(contentStr + '...') + ' '.repeat(Math.max(0, 50 - contentStr.length)) + colors.border(boxChar.vertical));
|
|
1001
|
+
// }
|
|
1002
|
+
// } else {
|
|
1003
|
+
// // OUTPUT
|
|
1004
|
+
// const response = data;
|
|
1005
|
+
// const message = extra;
|
|
1006
|
+
//
|
|
1007
|
+
// console.log(colors.border(`${boxChar.vertical}`) + ' 📋 MODEL: ' +
|
|
1008
|
+
// colors.text(response.model || 'unknown') + ' '.repeat(45) + colors.border(boxChar.vertical));
|
|
1009
|
+
//
|
|
1010
|
+
// console.log(colors.border(`${boxChar.vertical}`) + ' ⏱️ TOKENS: ' +
|
|
1011
|
+
// colors.text(`Prompt: ${response.usage?.prompt_tokens || '?'}, Completion: ${response.usage?.completion_tokens || '?'}`) +
|
|
1012
|
+
// ' '.repeat(15) + colors.border(boxChar.vertical));
|
|
1013
|
+
//
|
|
1014
|
+
// console.log(colors.border(`${boxChar.vertical}`) + ' 🔧 TOOL_CALLS: ' +
|
|
1015
|
+
// colors.text((message.tool_calls?.length || 0).toString()) + ' 个' + ' '.repeat(37) + colors.border(boxChar.vertical));
|
|
1016
|
+
//
|
|
1017
|
+
// // Content preview
|
|
1018
|
+
// const contentStr = typeof message.content === 'string'
|
|
1019
|
+
// ? message.content.substring(0, 100)
|
|
1020
|
+
// : JSON.stringify(message.content).substring(0, 100);
|
|
1021
|
+
// console.log(colors.border(`${boxChar.vertical}`) + ' 📝 CONTENT: ' +
|
|
1022
|
+
// colors.textDim(contentStr + '...') + ' '.repeat(Math.max(0, 40 - contentStr.length)) + colors.border(boxChar.vertical));
|
|
1023
|
+
// }
|
|
1024
|
+
//
|
|
1025
|
+
// console.log(colors.border(
|
|
1026
|
+
// `${boxChar.bottomLeft}${boxChar.horizontal.repeat(58)}${boxChar.bottomRight}`
|
|
1027
|
+
// ));
|
|
1028
|
+
// }
|
|
1029
|
+
shutdown() {
|
|
1030
|
+
this.rl.close();
|
|
1031
|
+
this.mcpManager.disconnectAllServers();
|
|
1032
|
+
this.cancellationManager.cleanup();
|
|
1033
|
+
// End the current session
|
|
1034
|
+
this.sessionManager.completeCurrentSession();
|
|
1035
|
+
const separator = icons.separator.repeat(40);
|
|
1036
|
+
console.log('');
|
|
1037
|
+
console.log(colors.border(separator));
|
|
1038
|
+
console.log(colors.primaryBright(`${icons.sparkles} Goodbye!`));
|
|
1039
|
+
console.log(colors.border(separator));
|
|
1040
|
+
console.log('');
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
export async function startInteractiveSession() {
|
|
1044
|
+
const session = new InteractiveSession();
|
|
1045
|
+
// Flag to control shutdown
|
|
1046
|
+
session._isShuttingDown = false;
|
|
1047
|
+
// Also listen for raw Ctrl+C on stdin (works in Windows PowerShell)
|
|
1048
|
+
process.stdin.on('data', (chunk) => {
|
|
1049
|
+
const str = chunk.toString();
|
|
1050
|
+
// Ctrl+C is character 0x03 or string '\u0003'
|
|
1051
|
+
if (str === '\u0003' || str.charCodeAt(0) === 3) {
|
|
1052
|
+
if (!session._isShuttingDown) {
|
|
1053
|
+
session._isShuttingDown = true;
|
|
1054
|
+
// Print goodbye immediately
|
|
1055
|
+
const separator = icons.separator.repeat(40);
|
|
1056
|
+
process.stdout.write('\n' + colors.border(separator) + '\n');
|
|
1057
|
+
process.stdout.write(colors.primaryBright(`${icons.sparkles} Goodbye!`) + '\n');
|
|
1058
|
+
process.stdout.write(colors.border(separator) + '\n\n');
|
|
1059
|
+
// Force exit
|
|
1060
|
+
process.exit(0);
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
});
|
|
1064
|
+
process.on('SIGINT', () => {
|
|
1065
|
+
if (session._isShuttingDown) {
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
1068
|
+
session._isShuttingDown = true;
|
|
1069
|
+
// Remove all SIGINT listeners to prevent re-entry
|
|
1070
|
+
process.removeAllListeners('SIGINT');
|
|
1071
|
+
// Print goodbye immediately
|
|
1072
|
+
const separator = icons.separator.repeat(40);
|
|
1073
|
+
process.stdout.write('\n' + colors.border(separator) + '\n');
|
|
1074
|
+
process.stdout.write(colors.primaryBright(`${icons.sparkles} Goodbye!`) + '\n');
|
|
1075
|
+
process.stdout.write(colors.border(separator) + '\n\n');
|
|
1076
|
+
// Force exit
|
|
1077
|
+
process.exit(0);
|
|
1078
|
+
});
|
|
1079
|
+
await session.start();
|
|
1080
|
+
}
|
|
1081
|
+
//# sourceMappingURL=session.js.map
|