sumulige-claude 1.0.8 → 1.0.11
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/.claude/.version +1 -0
- package/.claude/AGENTS.md +9 -9
- package/.claude/commands/commit-push-pr.md +23 -3
- package/.claude/sessions/active-sessions.json +1 -359
- package/.claude/settings.local.json +31 -1
- package/.claude/skills/algorithmic-art/LICENSE.txt +202 -0
- package/.claude/skills/algorithmic-art/SKILL.md +405 -0
- package/.claude/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/.claude/skills/algorithmic-art/templates/viewer.html +599 -0
- package/.claude/skills/brand-guidelines/LICENSE.txt +202 -0
- package/.claude/skills/brand-guidelines/SKILL.md +73 -0
- package/.claude/skills/canvas-design/LICENSE.txt +202 -0
- package/.claude/skills/canvas-design/SKILL.md +130 -0
- package/.claude/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/.claude/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/.claude/skills/doc-coauthoring/SKILL.md +375 -0
- package/.claude/skills/docx/LICENSE.txt +30 -0
- package/.claude/skills/docx/SKILL.md +197 -0
- package/.claude/skills/docx/docx-js.md +350 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.claude/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.claude/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.claude/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.claude/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.claude/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.claude/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/.claude/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/.claude/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/.claude/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/.claude/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.claude/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.claude/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.claude/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.claude/skills/docx/ooxml/scripts/pack.py +159 -0
- package/.claude/skills/docx/ooxml/scripts/unpack.py +29 -0
- package/.claude/skills/docx/ooxml/scripts/validate.py +69 -0
- package/.claude/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/.claude/skills/docx/ooxml/scripts/validation/base.py +951 -0
- package/.claude/skills/docx/ooxml/scripts/validation/docx.py +274 -0
- package/.claude/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/.claude/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/.claude/skills/docx/ooxml.md +610 -0
- package/.claude/skills/docx/scripts/__init__.py +1 -0
- package/.claude/skills/docx/scripts/document.py +1276 -0
- package/.claude/skills/docx/scripts/templates/comments.xml +3 -0
- package/.claude/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/.claude/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/.claude/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/.claude/skills/docx/scripts/templates/people.xml +3 -0
- package/.claude/skills/docx/scripts/utilities.py +374 -0
- package/.claude/skills/frontend-design/LICENSE.txt +177 -0
- package/.claude/skills/frontend-design/SKILL.md +42 -0
- package/.claude/skills/internal-comms/LICENSE.txt +202 -0
- package/.claude/skills/internal-comms/SKILL.md +32 -0
- package/.claude/skills/internal-comms/examples/3p-updates.md +47 -0
- package/.claude/skills/internal-comms/examples/company-newsletter.md +65 -0
- package/.claude/skills/internal-comms/examples/faq-answers.md +30 -0
- package/.claude/skills/internal-comms/examples/general-comms.md +16 -0
- package/.claude/skills/mcp-builder/LICENSE.txt +202 -0
- package/.claude/skills/mcp-builder/SKILL.md +236 -0
- package/.claude/skills/mcp-builder/reference/evaluation.md +602 -0
- package/.claude/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/.claude/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/.claude/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/.claude/skills/mcp-builder/scripts/connections.py +151 -0
- package/.claude/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/.claude/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/.claude/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/.claude/skills/pdf/LICENSE.txt +30 -0
- package/.claude/skills/pdf/SKILL.md +294 -0
- package/.claude/skills/pdf/forms.md +205 -0
- package/.claude/skills/pdf/reference.md +612 -0
- package/.claude/skills/pdf/scripts/check_bounding_boxes.py +70 -0
- package/.claude/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/.claude/skills/pdf/scripts/check_fillable_fields.py +12 -0
- package/.claude/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/.claude/skills/pdf/scripts/create_validation_image.py +41 -0
- package/.claude/skills/pdf/scripts/extract_form_field_info.py +152 -0
- package/.claude/skills/pdf/scripts/fill_fillable_fields.py +114 -0
- package/.claude/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/.claude/skills/pptx/LICENSE.txt +30 -0
- package/.claude/skills/pptx/SKILL.md +484 -0
- package/.claude/skills/pptx/html2pptx.md +625 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.claude/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.claude/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.claude/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.claude/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.claude/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.claude/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/.claude/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/.claude/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/.claude/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/.claude/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.claude/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.claude/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.claude/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.claude/skills/pptx/ooxml/scripts/pack.py +159 -0
- package/.claude/skills/pptx/ooxml/scripts/unpack.py +29 -0
- package/.claude/skills/pptx/ooxml/scripts/validate.py +69 -0
- package/.claude/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/.claude/skills/pptx/ooxml/scripts/validation/base.py +951 -0
- package/.claude/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/.claude/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/.claude/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/.claude/skills/pptx/ooxml.md +427 -0
- package/.claude/skills/pptx/scripts/html2pptx.js +979 -0
- package/.claude/skills/pptx/scripts/inventory.py +1020 -0
- package/.claude/skills/pptx/scripts/rearrange.py +231 -0
- package/.claude/skills/pptx/scripts/replace.py +385 -0
- package/.claude/skills/pptx/scripts/thumbnail.py +450 -0
- package/.claude/skills/skill-creator/LICENSE.txt +202 -0
- package/.claude/skills/skill-creator/SKILL.md +356 -0
- package/.claude/skills/skill-creator/references/output-patterns.md +82 -0
- package/.claude/skills/skill-creator/references/workflows.md +28 -0
- package/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/.claude/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/.claude/skills/slack-gif-creator/LICENSE.txt +202 -0
- package/.claude/skills/slack-gif-creator/SKILL.md +254 -0
- package/.claude/skills/slack-gif-creator/core/easing.py +234 -0
- package/.claude/skills/slack-gif-creator/core/frame_composer.py +176 -0
- package/.claude/skills/slack-gif-creator/core/gif_builder.py +269 -0
- package/.claude/skills/slack-gif-creator/core/validators.py +136 -0
- package/.claude/skills/slack-gif-creator/requirements.txt +4 -0
- package/.claude/skills/template/SKILL.md +6 -0
- package/.claude/skills/theme-factory/LICENSE.txt +202 -0
- package/.claude/skills/theme-factory/SKILL.md +59 -0
- package/.claude/skills/theme-factory/theme-showcase.pdf +0 -0
- package/.claude/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/.claude/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/.claude/skills/theme-factory/themes/desert-rose.md +19 -0
- package/.claude/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/.claude/skills/theme-factory/themes/golden-hour.md +19 -0
- package/.claude/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/.claude/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/.claude/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/.claude/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/.claude/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/.claude/skills/web-artifacts-builder/LICENSE.txt +202 -0
- package/.claude/skills/web-artifacts-builder/SKILL.md +74 -0
- package/.claude/skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/.claude/skills/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/.claude/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/.claude/skills/webapp-testing/LICENSE.txt +202 -0
- package/.claude/skills/webapp-testing/SKILL.md +96 -0
- package/.claude/skills/webapp-testing/examples/console_logging.py +35 -0
- package/.claude/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/.claude/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/.claude/skills/webapp-testing/scripts/with_server.py +106 -0
- package/.claude/skills/xlsx/LICENSE.txt +30 -0
- package/.claude/skills/xlsx/SKILL.md +289 -0
- package/.claude/skills/xlsx/recalc.py +178 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/AGENTS.md +165 -86
- package/README.md +22 -0
- package/cli.js +7 -2
- package/development/todos/INDEX.md +10 -1
- package/jest.config.js +61 -0
- package/lib/commands.js +67 -0
- package/lib/migrations.js +154 -0
- package/package.json +7 -2
- package/scripts/fix-hooks.mjs +97 -0
- package/template/.claude/commands/commit-push-pr.md +23 -3
- package/template/.claude/hooks/conversation-logger.cjs +222 -0
- package/template/.claude/settings.json +114 -45
- package/tests/README.md +263 -0
- package/tests/commands.test.js +163 -0
- package/tests/config.test.js +100 -0
- package/tests/marketplace.test.js +304 -0
- package/tests/migrations.test.js +187 -0
- package/tests/utils.test.js +167 -0
|
@@ -1,46 +1,115 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
2
|
+
"UserPromptSubmit": [
|
|
3
|
+
{
|
|
4
|
+
"matcher": {},
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/project-kickoff.cjs",
|
|
9
|
+
"timeout": 1000
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "command",
|
|
13
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/rag-skill-loader.cjs",
|
|
14
|
+
"timeout": 1000
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "command",
|
|
18
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs",
|
|
19
|
+
"timeout": 1000
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"type": "command",
|
|
23
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs",
|
|
24
|
+
"timeout": 1000
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "command",
|
|
28
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs",
|
|
29
|
+
"timeout": 1000
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"PreToolUse": [
|
|
35
|
+
{
|
|
36
|
+
"matcher": {},
|
|
37
|
+
"hooks": [
|
|
38
|
+
{
|
|
39
|
+
"type": "command",
|
|
40
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs",
|
|
41
|
+
"timeout": 1000
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": "command",
|
|
45
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs",
|
|
46
|
+
"timeout": 1000
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"type": "command",
|
|
50
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs",
|
|
51
|
+
"timeout": 1000
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"PostToolUse": [
|
|
57
|
+
{
|
|
58
|
+
"matcher": {},
|
|
59
|
+
"hooks": [
|
|
60
|
+
{
|
|
61
|
+
"type": "command",
|
|
62
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/code-formatter.cjs",
|
|
63
|
+
"timeout": 5000
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"type": "command",
|
|
67
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/verify-work.cjs",
|
|
68
|
+
"timeout": 1000
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"type": "command",
|
|
72
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs",
|
|
73
|
+
"timeout": 1000
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"type": "command",
|
|
77
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs",
|
|
78
|
+
"timeout": 1000
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"type": "command",
|
|
82
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs",
|
|
83
|
+
"timeout": 1000
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
"AgentStop": [
|
|
89
|
+
{
|
|
90
|
+
"matcher": {},
|
|
91
|
+
"hooks": [
|
|
92
|
+
{
|
|
93
|
+
"type": "command",
|
|
94
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/verify-work.cjs",
|
|
95
|
+
"timeout": 1000
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"type": "command",
|
|
99
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs",
|
|
100
|
+
"timeout": 1000
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"type": "command",
|
|
104
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs",
|
|
105
|
+
"timeout": 1000
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"type": "command",
|
|
109
|
+
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs",
|
|
110
|
+
"timeout": 1000
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
package/tests/README.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Sumulige Claude - 测试计划与报告
|
|
2
|
+
|
|
3
|
+
> 测试覆盖所有核心模块,确保代码质量
|
|
4
|
+
> 最后更新:2025-01-15
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📊 测试覆盖率概览
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Test Suites: 5 passed, 5 total
|
|
12
|
+
Tests: 78 passed, 78 total
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
| 模块 | 语句覆盖率 | 分支覆盖率 | 函数覆盖率 | 行覆盖率 | 状态 |
|
|
16
|
+
|------|-----------|-----------|-----------|---------|------|
|
|
17
|
+
| utils.js | 100% | 100% | 100% | 100% | ✅ |
|
|
18
|
+
| migrations.js | 86.66% | 75% | 87.5% | 88.67% | ✅ |
|
|
19
|
+
| config.js | 86.2% | 90.9% | 75% | 86.2% | ✅ |
|
|
20
|
+
| marketplace.js | 28.11% | 11.5% | 50% | 29.41% | ⚠️ |
|
|
21
|
+
| commands.js | 26.23% | 15.38% | 37.03% | 26.37% | ⚠️ |
|
|
22
|
+
| **总体** | **36.58%** | **26.95%** | **54.38%** | **36.72%** | 📊 |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 🧪 测试文件结构
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
tests/
|
|
30
|
+
├── README.md # 本文档
|
|
31
|
+
├── utils.test.js # 工具函数测试 (100%)
|
|
32
|
+
├── config.test.js # 配置管理测试 (86.2%)
|
|
33
|
+
├── migrations.test.js # 版本迁移测试 (86.66%)
|
|
34
|
+
├── marketplace.test.js # 市场功能测试 (28.11%)
|
|
35
|
+
└── commands.test.js # CLI 命令测试 (26.23%)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📋 测试用例详情
|
|
41
|
+
|
|
42
|
+
### utils.test.js (23 tests)
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
// copyRecursive - 递归复制目录
|
|
46
|
+
✓ should return 0 when source does not exist
|
|
47
|
+
✓ should copy files recursively
|
|
48
|
+
✓ should set execute permission for script files
|
|
49
|
+
✓ should not overwrite when overwrite=false
|
|
50
|
+
✓ should overwrite when overwrite=true
|
|
51
|
+
|
|
52
|
+
// ensureDir - 创建目录
|
|
53
|
+
✓ should create directory if not exists
|
|
54
|
+
✓ should not error if directory already exists
|
|
55
|
+
✓ should create nested directories
|
|
56
|
+
|
|
57
|
+
// toTitleCase - 标题大小写转换
|
|
58
|
+
✓ should convert string to title case
|
|
59
|
+
✓ should handle single word
|
|
60
|
+
✓ should handle empty string
|
|
61
|
+
✓ should handle already capitalized string
|
|
62
|
+
✓ should handle strings with multiple spaces
|
|
63
|
+
✓ should preserve special characters
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### config.test.js (7 tests)
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
✓ should return default config when no user config exists
|
|
70
|
+
✓ should return DEFAULTS constant
|
|
71
|
+
✓ should create directory and save config
|
|
72
|
+
✓ should not error when directory exists
|
|
73
|
+
✓ should export required constants
|
|
74
|
+
✓ should have correct paths
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### migrations.test.js (18 tests)
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
// getProjectVersion
|
|
81
|
+
✓ should return 1.0.0 when version file does not exist
|
|
82
|
+
✓ should read version from file
|
|
83
|
+
✓ should trim whitespace from version
|
|
84
|
+
✓ should return 1.0.0 on read error
|
|
85
|
+
|
|
86
|
+
// setProjectVersion
|
|
87
|
+
✓ should write version to file
|
|
88
|
+
✓ should add newline after version
|
|
89
|
+
✓ should create .claude directory if not exists
|
|
90
|
+
|
|
91
|
+
// compareVersions
|
|
92
|
+
✓ should return -1 when v1 < v2
|
|
93
|
+
✓ should return 1 when v1 > v2
|
|
94
|
+
✓ should return 0 when v1 === v2
|
|
95
|
+
✓ should handle version comparison correctly
|
|
96
|
+
✓ should handle version strings with different formats
|
|
97
|
+
|
|
98
|
+
// runMigrations
|
|
99
|
+
✓ should return success when already at latest version
|
|
100
|
+
✓ should return success when version is newer than template
|
|
101
|
+
✓ should return correct structure when pending migrations exist
|
|
102
|
+
✓ should handle missing settings.json gracefully
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### marketplace.test.js (18 tests)
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
// parseSimpleYaml
|
|
109
|
+
✓ should parse version number
|
|
110
|
+
✓ should parse skill names
|
|
111
|
+
✓ should handle empty skills array
|
|
112
|
+
✓ should skip comments
|
|
113
|
+
✓ should handle empty lines
|
|
114
|
+
|
|
115
|
+
// marketplaceCommands
|
|
116
|
+
✓ marketplace:list - should be a function
|
|
117
|
+
✓ marketplace:list - should output to console
|
|
118
|
+
✓ marketplace:install - should show usage when no skill name provided
|
|
119
|
+
✓ marketplace:sync - should be a function
|
|
120
|
+
✓ marketplace:sync - should output sync message
|
|
121
|
+
✓ marketplace:add - should show usage when no repo provided
|
|
122
|
+
✓ marketplace:add - should validate repo format
|
|
123
|
+
✓ marketplace:remove - should show usage when no skill name provided
|
|
124
|
+
✓ marketplace:status - should be a function
|
|
125
|
+
✓ marketplace:status - should output status information
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### commands.test.js (12 tests)
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
// exports
|
|
132
|
+
✓ should export runCommand function
|
|
133
|
+
✓ should export commands object
|
|
134
|
+
✓ should have all expected commands
|
|
135
|
+
|
|
136
|
+
// runCommand
|
|
137
|
+
✓ should call the correct command function
|
|
138
|
+
✓ should pass arguments to command function
|
|
139
|
+
✓ should handle unknown commands gracefully
|
|
140
|
+
|
|
141
|
+
// init
|
|
142
|
+
✓ should be a function
|
|
143
|
+
✓ should not throw
|
|
144
|
+
|
|
145
|
+
// sync
|
|
146
|
+
✓ should be a function
|
|
147
|
+
✓ should not throw
|
|
148
|
+
|
|
149
|
+
// agent
|
|
150
|
+
✓ should show usage when no task provided
|
|
151
|
+
✓ should display agent information when task provided
|
|
152
|
+
|
|
153
|
+
// skill:create
|
|
154
|
+
✓ should show usage when no skill name provided
|
|
155
|
+
✓ should validate skill name format
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 🚀 运行测试
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# 运行所有测试
|
|
164
|
+
npm test
|
|
165
|
+
|
|
166
|
+
# 运行测试并生成覆盖率报告
|
|
167
|
+
npm run test:coverage
|
|
168
|
+
|
|
169
|
+
# 监视模式
|
|
170
|
+
npm run test:watch
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 📦 依赖项
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"devDependencies": {
|
|
180
|
+
"jest": "^30.2.0",
|
|
181
|
+
"mock-fs": "^5.5.0",
|
|
182
|
+
"prettier": "^3.7.4",
|
|
183
|
+
"sinon": "^21.0.1",
|
|
184
|
+
"yaml": "^2.8.2"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 🔧 测试策略
|
|
192
|
+
|
|
193
|
+
### 使用的工具
|
|
194
|
+
|
|
195
|
+
| 工具 | 用途 |
|
|
196
|
+
|------|------|
|
|
197
|
+
| Jest | 测试框架 + 断言 |
|
|
198
|
+
| mock-fs | 文件系统模拟 |
|
|
199
|
+
| sinon | 函数 stub 和 spy |
|
|
200
|
+
|
|
201
|
+
### Mock 策略
|
|
202
|
+
|
|
203
|
+
1. **文件系统操作**:使用 `mock-fs` 模拟文件系统
|
|
204
|
+
2. **外部命令**:使用 `sinon.stub` 模拟 `execSync`
|
|
205
|
+
3. **Console 输出**:使用 `jest.spyOn(console, 'log')` 捕获输出
|
|
206
|
+
|
|
207
|
+
### 已知限制
|
|
208
|
+
|
|
209
|
+
1. **commands.js** 覆盖率低 - 该模块依赖外部命令和实际文件操作
|
|
210
|
+
2. **marketplace.js** YAML 解析逻辑复杂,简化了测试场景
|
|
211
|
+
3. 集成测试未覆盖,建议后续添加端到端测试
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 🎯 改进建议
|
|
216
|
+
|
|
217
|
+
### 短期改进
|
|
218
|
+
|
|
219
|
+
1. 为 commands.js 添加更多单元测试(目标:40%+)
|
|
220
|
+
2. 补充 marketplace.js 的 YAML 解析边界测试
|
|
221
|
+
3. 添加错误处理的测试用例
|
|
222
|
+
|
|
223
|
+
### 长期改进
|
|
224
|
+
|
|
225
|
+
1. 添加集成测试覆盖完整的 CLI 工作流
|
|
226
|
+
2. 添加性能测试确保大型项目下的响应速度
|
|
227
|
+
3. 考虑添加快照测试用于模板文件验证
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 📝 测试最佳实践
|
|
232
|
+
|
|
233
|
+
### 遵循的原则
|
|
234
|
+
|
|
235
|
+
1. **AAA 模式**:Arrange-Act-Assert
|
|
236
|
+
2. **单一职责**:每个测试只验证一个行为
|
|
237
|
+
3. **独立性**:测试之间不共享状态
|
|
238
|
+
4. **可读性**:测试名称清晰描述测试内容
|
|
239
|
+
|
|
240
|
+
### 示例
|
|
241
|
+
|
|
242
|
+
```javascript
|
|
243
|
+
describe('toTitleCase', () => {
|
|
244
|
+
it('should convert string to title case', () => {
|
|
245
|
+
// Arrange
|
|
246
|
+
const input = 'hello world';
|
|
247
|
+
|
|
248
|
+
// Act
|
|
249
|
+
const result = utils.toTitleCase(input);
|
|
250
|
+
|
|
251
|
+
// Assert
|
|
252
|
+
expect(result).toBe('Hello World');
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 🔗 相关资源
|
|
260
|
+
|
|
261
|
+
- [Jest 文档](https://jestjs.io/)
|
|
262
|
+
- [mock-fs 文档](https://github.com/tschaub/mock-fs)
|
|
263
|
+
- [Sinon.JS 文档](https://sinonjs.org/)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commands 模块单元测试 - 简化版
|
|
3
|
+
* 使用基本的验证而非复杂的 mock-fs
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const commands = require('../lib/commands');
|
|
7
|
+
|
|
8
|
+
describe('Commands Module - Basic Tests', () => {
|
|
9
|
+
describe('exports', () => {
|
|
10
|
+
it('should export runCommand function', () => {
|
|
11
|
+
expect(typeof commands.runCommand).toBe('function');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should export commands object', () => {
|
|
15
|
+
expect(typeof commands.commands).toBe('object');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should have all expected commands', () => {
|
|
19
|
+
const cmdList = commands.commands;
|
|
20
|
+
expect(cmdList.init).toBeDefined();
|
|
21
|
+
expect(cmdList.sync).toBeDefined();
|
|
22
|
+
expect(cmdList.migrate).toBeDefined();
|
|
23
|
+
expect(cmdList.agent).toBeDefined();
|
|
24
|
+
expect(cmdList.status).toBeDefined();
|
|
25
|
+
expect(cmdList['skill:list']).toBeDefined();
|
|
26
|
+
expect(cmdList['skill:create']).toBeDefined();
|
|
27
|
+
expect(cmdList['skill:check']).toBeDefined();
|
|
28
|
+
expect(cmdList['skill:install']).toBeDefined();
|
|
29
|
+
expect(cmdList.template).toBeDefined();
|
|
30
|
+
expect(cmdList.kickoff).toBeDefined();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('runCommand', () => {
|
|
35
|
+
it('should call the correct command function', () => {
|
|
36
|
+
const initSpy = jest.spyOn(commands.commands, 'init');
|
|
37
|
+
commands.runCommand('init', []);
|
|
38
|
+
expect(initSpy).toHaveBeenCalled();
|
|
39
|
+
initSpy.mockRestore();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should pass arguments to command function', () => {
|
|
43
|
+
const agentSpy = jest.spyOn(commands.commands, 'agent');
|
|
44
|
+
commands.runCommand('agent', ['test task']);
|
|
45
|
+
expect(agentSpy).toHaveBeenCalledWith('test task');
|
|
46
|
+
agentSpy.mockRestore();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should handle unknown commands gracefully', () => {
|
|
50
|
+
expect(() => {
|
|
51
|
+
commands.runCommand('unknown-command', []);
|
|
52
|
+
}).not.toThrow();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe('init command', () => {
|
|
57
|
+
it('should be a function', () => {
|
|
58
|
+
expect(typeof commands.commands.init).toBe('function');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should not throw', () => {
|
|
62
|
+
expect(() => commands.commands.init()).not.toThrow();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('sync command', () => {
|
|
67
|
+
it('should be a function', () => {
|
|
68
|
+
expect(typeof commands.commands.sync).toBe('function');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should not throw', () => {
|
|
72
|
+
expect(() => commands.commands.sync()).not.toThrow();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('migrate command', () => {
|
|
77
|
+
it('should be a function', () => {
|
|
78
|
+
expect(typeof commands.commands.migrate).toBe('function');
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('agent command', () => {
|
|
83
|
+
it('should show usage when no task provided', () => {
|
|
84
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
85
|
+
commands.commands.agent();
|
|
86
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
87
|
+
const output = consoleSpy.mock.calls.flat().join(' ');
|
|
88
|
+
expect(output).toContain('Usage');
|
|
89
|
+
consoleSpy.mockRestore();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should display agent information when task provided', () => {
|
|
93
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
94
|
+
commands.commands.agent('Build a REST API');
|
|
95
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
96
|
+
const output = consoleSpy.mock.calls.flat().join(' ');
|
|
97
|
+
expect(output).toContain('Agent Orchestration');
|
|
98
|
+
expect(output).toContain('Build a REST API');
|
|
99
|
+
consoleSpy.mockRestore();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('status command', () => {
|
|
104
|
+
it('should be a function', () => {
|
|
105
|
+
expect(typeof commands.commands.status).toBe('function');
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('skill:list command', () => {
|
|
110
|
+
it('should be a function', () => {
|
|
111
|
+
expect(typeof commands.commands['skill:list']).toBe('function');
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('skill:create command', () => {
|
|
116
|
+
it('should show usage when no skill name provided', () => {
|
|
117
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
118
|
+
commands.commands['skill:create']();
|
|
119
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
120
|
+
const output = consoleSpy.mock.calls.flat().join(' ');
|
|
121
|
+
expect(output).toContain('Usage');
|
|
122
|
+
consoleSpy.mockRestore();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should validate skill name format', () => {
|
|
126
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
127
|
+
commands.commands['skill:create']('Invalid_Name');
|
|
128
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
129
|
+
const output = consoleSpy.mock.calls.flat().join(' ');
|
|
130
|
+
expect(output).toContain('Invalid skill name');
|
|
131
|
+
consoleSpy.mockRestore();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('skill:check command', () => {
|
|
136
|
+
it('should be a function', () => {
|
|
137
|
+
expect(typeof commands.commands['skill:check']).toBe('function');
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe('skill:install command', () => {
|
|
142
|
+
it('should show usage when no source provided', () => {
|
|
143
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
144
|
+
commands.commands['skill:install']();
|
|
145
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
146
|
+
const output = consoleSpy.mock.calls.flat().join(' ');
|
|
147
|
+
expect(output).toContain('Usage');
|
|
148
|
+
consoleSpy.mockRestore();
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe('template command', () => {
|
|
153
|
+
it('should be a function', () => {
|
|
154
|
+
expect(typeof commands.commands.template).toBe('function');
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe('kickoff command', () => {
|
|
159
|
+
it('should be a function', () => {
|
|
160
|
+
expect(typeof commands.commands.kickoff).toBe('function');
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config 模块单元测试
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
|
|
9
|
+
describe('Config Module', () => {
|
|
10
|
+
const config = require('../lib/config');
|
|
11
|
+
|
|
12
|
+
describe('loadConfig', () => {
|
|
13
|
+
it('should return default config when no user config exists', () => {
|
|
14
|
+
// 使用真实的 CONFIG_DIR 但临时移除 config.json
|
|
15
|
+
const realConfigFile = config.CONFIG_FILE;
|
|
16
|
+
const tempBackup = realConfigFile + '.backup-test';
|
|
17
|
+
|
|
18
|
+
// 备份现有配置(如果存在)
|
|
19
|
+
if (fs.existsSync(realConfigFile)) {
|
|
20
|
+
fs.renameSync(realConfigFile, tempBackup);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const result = config.loadConfig();
|
|
25
|
+
|
|
26
|
+
expect(result).toBeDefined();
|
|
27
|
+
expect(result).toHaveProperty('version');
|
|
28
|
+
expect(result).toHaveProperty('agents');
|
|
29
|
+
expect(result).toHaveProperty('skills');
|
|
30
|
+
} finally {
|
|
31
|
+
// 恢复原配置
|
|
32
|
+
if (fs.existsSync(tempBackup)) {
|
|
33
|
+
fs.renameSync(tempBackup, realConfigFile);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return DEFAULTS constant', () => {
|
|
39
|
+
expect(config.DEFAULTS).toBeDefined();
|
|
40
|
+
expect(typeof config.DEFAULTS).toBe('object');
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('saveConfig & ensureDir', () => {
|
|
45
|
+
const tempDir = path.join(os.tmpdir(), 'smc-test-' + Date.now());
|
|
46
|
+
const tempFile = path.join(tempDir, 'test-config.json');
|
|
47
|
+
|
|
48
|
+
afterAll(() => {
|
|
49
|
+
// 清理
|
|
50
|
+
if (fs.existsSync(tempDir)) {
|
|
51
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should create directory and save config', () => {
|
|
56
|
+
const testConfig = {
|
|
57
|
+
version: '1.0.0',
|
|
58
|
+
test: 'value'
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// 直接调用 ensureDir
|
|
62
|
+
config.ensureDir(tempDir);
|
|
63
|
+
expect(fs.existsSync(tempDir)).toBe(true);
|
|
64
|
+
|
|
65
|
+
// 手动保存文件
|
|
66
|
+
fs.writeFileSync(tempFile, JSON.stringify(testConfig, null, 2));
|
|
67
|
+
expect(fs.existsSync(tempFile)).toBe(true);
|
|
68
|
+
|
|
69
|
+
const saved = JSON.parse(fs.readFileSync(tempFile, 'utf-8'));
|
|
70
|
+
expect(saved).toEqual(testConfig);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should not error when directory exists', () => {
|
|
74
|
+
expect(() => config.ensureDir(tempDir)).not.toThrow();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('deepMerge (internal behavior)', () => {
|
|
79
|
+
it('should have loadConfig and saveConfig functions', () => {
|
|
80
|
+
expect(typeof config.loadConfig).toBe('function');
|
|
81
|
+
expect(typeof config.saveConfig).toBe('function');
|
|
82
|
+
expect(typeof config.ensureDir).toBe('function');
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('exports', () => {
|
|
87
|
+
it('should export required constants', () => {
|
|
88
|
+
expect(config.CONFIG_DIR).toBeDefined();
|
|
89
|
+
expect(config.CONFIG_FILE).toBeDefined();
|
|
90
|
+
expect(config.DEFAULTS).toBeDefined();
|
|
91
|
+
expect(config.SKILLS_DIR).toBeDefined();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should have correct paths', () => {
|
|
95
|
+
expect(config.CONFIG_DIR).toContain('.claude');
|
|
96
|
+
expect(config.CONFIG_FILE).toContain('config.json');
|
|
97
|
+
expect(config.SKILLS_DIR).toContain('skills');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|