sumulige-claude 1.0.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/.version +1 -0
- package/.claude/AGENTS.md +9 -9
- package/.claude/commands/commit-push-pr.md +23 -3
- package/.claude/commands/todos.md +41 -6
- package/.claude/hooks/session-restore.cjs +102 -0
- package/.claude/hooks/session-save.cjs +164 -0
- package/.claude/hooks/todo-manager.cjs +262 -141
- package/.claude/settings.local.json +25 -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/api-tester/SKILL.md +52 -23
- 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/test-workflow/SKILL.md +191 -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/templates/tasks/develop.md +69 -0
- package/.claude/templates/tasks/research.md +64 -0
- package/.claude/templates/tasks/test.md +96 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/.versionrc +25 -0
- package/AGENTS.md +171 -86
- package/CHANGELOG.md +83 -4
- package/PROJECT_STRUCTURE.md +40 -3
- package/Q&A.md +184 -0
- package/README.md +74 -2
- package/cli.js +79 -5
- package/config/official-skills.json +183 -0
- package/development/todos/.state.json +4 -0
- package/development/todos/INDEX.md +67 -32
- package/docs/RELEASE.md +93 -0
- package/jest.config.js +61 -0
- package/lib/commands.js +1724 -39
- package/lib/migrations.js +154 -0
- package/lib/utils.js +102 -14
- package/lib/version-check.js +169 -0
- package/package.json +13 -3
- package/scripts/fix-hooks.mjs +97 -0
- package/template/.claude/commands/commit-push-pr.md +23 -3
- package/template/.claude/hooks/project-kickoff.cjs +190 -1
- package/template/.claude/hooks/session-restore.cjs +102 -0
- package/template/.claude/hooks/session-save.cjs +164 -0
- package/template/.claude/settings.json +114 -50
- 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
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrations - Version control for project templates
|
|
3
|
+
*
|
|
4
|
+
* 每个迁移函数:
|
|
5
|
+
* - from: 起始版本
|
|
6
|
+
* - to: 目标版本
|
|
7
|
+
* - migrate: 实际迁移逻辑
|
|
8
|
+
*
|
|
9
|
+
* 迁移链:v1.0.0 → v1.0.2 → v1.0.10 → ...
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
|
|
15
|
+
// 当前模板版本
|
|
16
|
+
const TEMPLATE_VERSION = '1.0.10';
|
|
17
|
+
|
|
18
|
+
// 版本文件路径
|
|
19
|
+
const getVersionFile = (projectDir) => path.join(projectDir, '.claude', '.version');
|
|
20
|
+
|
|
21
|
+
// 读取项目版本
|
|
22
|
+
function getProjectVersion(projectDir) {
|
|
23
|
+
const versionFile = getVersionFile(projectDir);
|
|
24
|
+
if (!fs.existsSync(versionFile)) {
|
|
25
|
+
// 没有 version 文件说明是旧版本项目
|
|
26
|
+
return '1.0.0';
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return fs.readFileSync(versionFile, 'utf-8').trim();
|
|
30
|
+
} catch {
|
|
31
|
+
return '1.0.0';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 写入项目版本
|
|
36
|
+
function setProjectVersion(projectDir, version) {
|
|
37
|
+
const versionFile = getVersionFile(projectDir);
|
|
38
|
+
fs.writeFileSync(versionFile, version + '\n');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 版本比较
|
|
42
|
+
function compareVersions(v1, v2) {
|
|
43
|
+
const parts1 = v1.split('.').map(Number);
|
|
44
|
+
const parts2 = v2.split('.').map(Number);
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < 3; i++) {
|
|
47
|
+
if (parts1[i] < parts2[i]) return -1;
|
|
48
|
+
if (parts1[i] > parts2[i]) return 1;
|
|
49
|
+
}
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 迁移列表
|
|
54
|
+
const migrations = [
|
|
55
|
+
{
|
|
56
|
+
from: '1.0.0',
|
|
57
|
+
to: '1.0.10',
|
|
58
|
+
description: 'Migrate hooks format from old to new',
|
|
59
|
+
migrate: (projectDir) => {
|
|
60
|
+
const settingsFile = path.join(projectDir, '.claude', 'settings.json');
|
|
61
|
+
if (!fs.existsSync(settingsFile)) return;
|
|
62
|
+
|
|
63
|
+
let settings;
|
|
64
|
+
try {
|
|
65
|
+
settings = JSON.parse(fs.readFileSync(settingsFile, 'utf-8'));
|
|
66
|
+
} catch {
|
|
67
|
+
return; // 无效 JSON,跳过
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 检测旧格式
|
|
71
|
+
const isOldFormat = settings.matcher || (settings.hooks && typeof settings.hooks === 'object');
|
|
72
|
+
if (!isOldFormat) return;
|
|
73
|
+
|
|
74
|
+
// 读取新模板
|
|
75
|
+
const templateDir = path.join(__dirname, '../template');
|
|
76
|
+
const templateSettings = path.join(templateDir, '.claude', 'settings.json');
|
|
77
|
+
|
|
78
|
+
if (fs.existsSync(templateSettings)) {
|
|
79
|
+
fs.writeFileSync(settingsFile, fs.readFileSync(templateSettings, 'utf-8'));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 执行迁移
|
|
87
|
+
* @param {string} projectDir - 项目目录
|
|
88
|
+
* @param {boolean} silent - 是否静默模式
|
|
89
|
+
* @returns {object} { success, migrations, currentVersion }
|
|
90
|
+
*/
|
|
91
|
+
function runMigrations(projectDir, silent = false) {
|
|
92
|
+
const currentVersion = getProjectVersion(projectDir);
|
|
93
|
+
|
|
94
|
+
// 已经是最新版本
|
|
95
|
+
if (compareVersions(currentVersion, TEMPLATE_VERSION) >= 0) {
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
migrations: [],
|
|
99
|
+
currentVersion,
|
|
100
|
+
templateVersion: TEMPLATE_VERSION
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 找到需要执行的迁移
|
|
105
|
+
const pendingMigrations = migrations.filter(m => {
|
|
106
|
+
const cmp = compareVersions(currentVersion, m.to);
|
|
107
|
+
return cmp < 0; // 只执行版本高于当前版本的迁移
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// 按版本顺序执行
|
|
111
|
+
pendingMigrations.sort((a, b) => compareVersions(a.to, b.to));
|
|
112
|
+
|
|
113
|
+
const executed = [];
|
|
114
|
+
|
|
115
|
+
for (const migration of pendingMigrations) {
|
|
116
|
+
try {
|
|
117
|
+
if (!silent) {
|
|
118
|
+
console.log(`⬆️ Migrating: ${currentVersion} → ${migration.to}`);
|
|
119
|
+
console.log(` ${migration.description}`);
|
|
120
|
+
}
|
|
121
|
+
migration.migrate(projectDir);
|
|
122
|
+
executed.push(migration);
|
|
123
|
+
setProjectVersion(projectDir, migration.to);
|
|
124
|
+
if (!silent) {
|
|
125
|
+
console.log(` ✅ Done`);
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
if (!silent) {
|
|
129
|
+
console.log(` ❌ Failed: ${error.message}`);
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
success: false,
|
|
133
|
+
error: error.message,
|
|
134
|
+
currentVersion,
|
|
135
|
+
executed
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
success: true,
|
|
142
|
+
migrations: executed,
|
|
143
|
+
currentVersion: TEMPLATE_VERSION,
|
|
144
|
+
templateVersion: TEMPLATE_VERSION
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
module.exports = {
|
|
149
|
+
TEMPLATE_VERSION,
|
|
150
|
+
getProjectVersion,
|
|
151
|
+
setProjectVersion,
|
|
152
|
+
compareVersions,
|
|
153
|
+
runMigrations
|
|
154
|
+
};
|
package/lib/utils.js
CHANGED
|
@@ -8,20 +8,35 @@ const fs = require('fs');
|
|
|
8
8
|
const path = require('path');
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Copy mode for template deployment
|
|
12
|
+
*/
|
|
13
|
+
const CopyMode = {
|
|
14
|
+
SAFE: 'safe', // Skip existing files (no overwrite, no backup)
|
|
15
|
+
BACKUP: 'backup', // Backup then overwrite (default)
|
|
16
|
+
FORCE: 'force' // Overwrite without backup
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Recursively copy directory contents with backup support
|
|
12
21
|
* @param {string} src - Source directory
|
|
13
22
|
* @param {string} dest - Destination directory
|
|
14
|
-
* @param {boolean}
|
|
15
|
-
* @
|
|
23
|
+
* @param {boolean|string} mode - Copy mode: true/false (legacy) or CopyMode enum
|
|
24
|
+
* @param {string} backupDir - Backup directory path
|
|
25
|
+
* @returns {object} Copy result { copied, skipped, backedup }
|
|
16
26
|
*/
|
|
17
|
-
exports.copyRecursive = function(src, dest,
|
|
18
|
-
if (!fs.existsSync(src)) return 0;
|
|
27
|
+
exports.copyRecursive = function(src, dest, mode = CopyMode.BACKUP, backupDir = null) {
|
|
28
|
+
if (!fs.existsSync(src)) return { copied: 0, skipped: 0, backedup: 0 };
|
|
29
|
+
|
|
30
|
+
// Legacy support: convert boolean to CopyMode
|
|
31
|
+
if (typeof mode === 'boolean') {
|
|
32
|
+
mode = mode ? CopyMode.FORCE : CopyMode.SAFE;
|
|
33
|
+
}
|
|
19
34
|
|
|
20
35
|
if (!fs.existsSync(dest)) {
|
|
21
36
|
fs.mkdirSync(dest, { recursive: true });
|
|
22
37
|
}
|
|
23
38
|
|
|
24
|
-
|
|
39
|
+
const result = { copied: 0, skipped: 0, backedup: 0 };
|
|
25
40
|
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
26
41
|
|
|
27
42
|
for (const entry of entries) {
|
|
@@ -29,19 +44,89 @@ exports.copyRecursive = function(src, dest, overwrite = false) {
|
|
|
29
44
|
const destPath = path.join(dest, entry.name);
|
|
30
45
|
|
|
31
46
|
if (entry.isDirectory()) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
const subResult = exports.copyRecursive(
|
|
48
|
+
srcPath,
|
|
49
|
+
destPath,
|
|
50
|
+
mode,
|
|
51
|
+
backupDir ? path.join(backupDir, entry.name) : null
|
|
52
|
+
);
|
|
53
|
+
result.copied += subResult.copied;
|
|
54
|
+
result.skipped += subResult.skipped;
|
|
55
|
+
result.backedup += subResult.backedup;
|
|
56
|
+
} else {
|
|
57
|
+
const action = copyFile(srcPath, destPath, mode, backupDir);
|
|
58
|
+
result[action.type === 'copied' ? 'copied' : action.type]++;
|
|
59
|
+
if (action.type === 'backedup') {
|
|
60
|
+
result.copied++;
|
|
61
|
+
result.backedup++;
|
|
38
62
|
}
|
|
39
|
-
count++;
|
|
40
63
|
}
|
|
41
64
|
}
|
|
42
|
-
return
|
|
65
|
+
return result;
|
|
43
66
|
};
|
|
44
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Copy a single file with backup support
|
|
70
|
+
* @param {string} srcPath - Source file path
|
|
71
|
+
* @param {string} destPath - Destination file path
|
|
72
|
+
* @param {string} mode - Copy mode
|
|
73
|
+
* @param {string} backupDir - Backup directory path
|
|
74
|
+
* @returns {object} Action result { type, backupPath }
|
|
75
|
+
*/
|
|
76
|
+
function copyFile(srcPath, destPath, mode, backupDir) {
|
|
77
|
+
// File doesn't exist - just copy
|
|
78
|
+
if (!fs.existsSync(destPath)) {
|
|
79
|
+
fs.copyFileSync(srcPath, destPath);
|
|
80
|
+
setExecutablePermission(destPath);
|
|
81
|
+
return { type: 'copied' };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// File exists - handle based on mode
|
|
85
|
+
switch (mode) {
|
|
86
|
+
case CopyMode.SAFE:
|
|
87
|
+
// Skip existing files
|
|
88
|
+
return { type: 'skipped' };
|
|
89
|
+
|
|
90
|
+
case CopyMode.FORCE:
|
|
91
|
+
// Overwrite without backup
|
|
92
|
+
fs.copyFileSync(srcPath, destPath);
|
|
93
|
+
setExecutablePermission(destPath);
|
|
94
|
+
return { type: 'copied' };
|
|
95
|
+
|
|
96
|
+
case CopyMode.BACKUP:
|
|
97
|
+
default:
|
|
98
|
+
// Backup then overwrite
|
|
99
|
+
if (backupDir) {
|
|
100
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0];
|
|
101
|
+
const backupFileName = path.basename(destPath) + '.' + timestamp + '.bak';
|
|
102
|
+
const backupPath = path.join(backupDir, backupFileName);
|
|
103
|
+
|
|
104
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
105
|
+
fs.copyFileSync(destPath, backupPath);
|
|
106
|
+
setExecutablePermission(backupPath);
|
|
107
|
+
|
|
108
|
+
fs.copyFileSync(srcPath, destPath);
|
|
109
|
+
setExecutablePermission(destPath);
|
|
110
|
+
return { type: 'backedup', backupPath };
|
|
111
|
+
} else {
|
|
112
|
+
// No backup dir, just overwrite
|
|
113
|
+
fs.copyFileSync(srcPath, destPath);
|
|
114
|
+
setExecutablePermission(destPath);
|
|
115
|
+
return { type: 'copied' };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Set executable permission for script files
|
|
122
|
+
* @param {string} filePath - File path
|
|
123
|
+
*/
|
|
124
|
+
function setExecutablePermission(filePath) {
|
|
125
|
+
if (filePath.endsWith('.sh') || filePath.endsWith('.cjs')) {
|
|
126
|
+
fs.chmodSync(filePath, 0o755);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
45
130
|
/**
|
|
46
131
|
* Ensure a directory exists
|
|
47
132
|
* @param {string} dir - Directory path
|
|
@@ -60,3 +145,6 @@ exports.ensureDir = function(dir) {
|
|
|
60
145
|
exports.toTitleCase = function(str) {
|
|
61
146
|
return str.replace(/\b\w/g, char => char.toUpperCase());
|
|
62
147
|
};
|
|
148
|
+
|
|
149
|
+
// Export CopyMode for use in other modules
|
|
150
|
+
exports.CopyMode = CopyMode;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version Check - Check for updates from npm registry
|
|
3
|
+
*
|
|
4
|
+
* Implements lazy checking with local caching to minimize
|
|
5
|
+
* network requests and performance impact.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const https = require('https');
|
|
11
|
+
|
|
12
|
+
const CONFIG_DIR = path.join(process.env.HOME, '.claude');
|
|
13
|
+
const CHECK_FILE = path.join(CONFIG_DIR, '.last-update-check');
|
|
14
|
+
const ONE_DAY = 24 * 60 * 60 * 1000;
|
|
15
|
+
|
|
16
|
+
// Current version from package.json
|
|
17
|
+
const CURRENT_VERSION = require('../package.json').version;
|
|
18
|
+
const PACKAGE_NAME = 'sumulige-claude';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get timestamp of last update check
|
|
22
|
+
* @returns {number} Timestamp of last check, or 0 if never checked
|
|
23
|
+
*/
|
|
24
|
+
function getLastCheckTime() {
|
|
25
|
+
try {
|
|
26
|
+
const content = fs.readFileSync(CHECK_FILE, 'utf-8');
|
|
27
|
+
return parseInt(content, 10) || 0;
|
|
28
|
+
} catch {
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Save timestamp of current update check
|
|
35
|
+
* @param {number} timestamp - Timestamp to save
|
|
36
|
+
*/
|
|
37
|
+
function saveLastCheckTime(timestamp = Date.now()) {
|
|
38
|
+
try {
|
|
39
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
40
|
+
fs.writeFileSync(CHECK_FILE, timestamp.toString());
|
|
41
|
+
} catch {
|
|
42
|
+
// Ignore errors
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Fetch latest version from npm registry
|
|
48
|
+
* @returns {Promise<string|null>} Latest version or null if failed
|
|
49
|
+
*/
|
|
50
|
+
function fetchLatestVersion() {
|
|
51
|
+
return new Promise((resolve) => {
|
|
52
|
+
const options = {
|
|
53
|
+
hostname: 'registry.npmjs.org',
|
|
54
|
+
path: `/${PACKAGE_NAME}`,
|
|
55
|
+
timeout: 5000, // 5 second timeout
|
|
56
|
+
headers: {
|
|
57
|
+
'User-Agent': `${PACKAGE_NAME}/${CURRENT_VERSION}`
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const req = https.get(options, (res) => {
|
|
62
|
+
let data = '';
|
|
63
|
+
res.on('data', chunk => data += chunk);
|
|
64
|
+
res.on('end', () => {
|
|
65
|
+
try {
|
|
66
|
+
const pkg = JSON.parse(data);
|
|
67
|
+
resolve(pkg['dist-tags']?.latest || null);
|
|
68
|
+
} catch {
|
|
69
|
+
resolve(null);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
req.on('error', () => resolve(null));
|
|
75
|
+
req.on('timeout', () => {
|
|
76
|
+
req.destroy();
|
|
77
|
+
resolve(null);
|
|
78
|
+
});
|
|
79
|
+
req.setTimeout(5000);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Check for updates (with caching)
|
|
85
|
+
* @param {Object} options - Check options
|
|
86
|
+
* @param {boolean} options.force - Force check even if within cache period
|
|
87
|
+
* @param {boolean} options.silent - Don't print messages
|
|
88
|
+
* @returns {Promise<Object>} Check result { current, latest, updateAvailable }
|
|
89
|
+
*/
|
|
90
|
+
async function checkUpdate(options = {}) {
|
|
91
|
+
const { force = false, silent = false } = options;
|
|
92
|
+
const now = Date.now();
|
|
93
|
+
const lastCheck = getLastCheckTime();
|
|
94
|
+
const shouldCheck = force || (now - lastCheck > ONE_DAY);
|
|
95
|
+
|
|
96
|
+
if (!shouldCheck) {
|
|
97
|
+
return {
|
|
98
|
+
current: CURRENT_VERSION,
|
|
99
|
+
latest: null,
|
|
100
|
+
updateAvailable: false,
|
|
101
|
+
cached: true
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const latest = await fetchLatestVersion();
|
|
106
|
+
saveLastCheckTime(now);
|
|
107
|
+
|
|
108
|
+
// Only show update if remote version is NEWER than current
|
|
109
|
+
const updateAvailable = latest && compareVersions(latest, CURRENT_VERSION) > 0;
|
|
110
|
+
const result = {
|
|
111
|
+
current: CURRENT_VERSION,
|
|
112
|
+
latest,
|
|
113
|
+
updateAvailable,
|
|
114
|
+
cached: false
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
if (!silent && updateAvailable) {
|
|
118
|
+
console.log('');
|
|
119
|
+
console.log(`💡 新版本 v${latest} 可用 (当前: v${CURRENT_VERSION})`);
|
|
120
|
+
console.log(` 运行: npm update -g ${PACKAGE_NAME}`);
|
|
121
|
+
console.log('');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get current version
|
|
129
|
+
* @returns {string} Current version
|
|
130
|
+
*/
|
|
131
|
+
function getCurrentVersion() {
|
|
132
|
+
return CURRENT_VERSION;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Parse version string to comparable array
|
|
137
|
+
* @param {string} version - Version string (e.g., "1.2.3")
|
|
138
|
+
* @returns {number[]} Comparable array [major, minor, patch]
|
|
139
|
+
*/
|
|
140
|
+
function parseVersion(version) {
|
|
141
|
+
return version.split('.').map(Number).filter(n => !isNaN(n));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Compare two versions
|
|
146
|
+
* @param {string} v1 - First version
|
|
147
|
+
* @param {string} v2 - Second version
|
|
148
|
+
* @returns {number} -1 if v1 < v2, 0 if equal, 1 if v1 > v2
|
|
149
|
+
*/
|
|
150
|
+
function compareVersions(v1, v2) {
|
|
151
|
+
const parts1 = parseVersion(v1);
|
|
152
|
+
const parts2 = parseVersion(v2);
|
|
153
|
+
const maxLen = Math.max(parts1.length, parts2.length);
|
|
154
|
+
|
|
155
|
+
for (let i = 0; i < maxLen; i++) {
|
|
156
|
+
const p1 = parts1[i] || 0;
|
|
157
|
+
const p2 = parts2[i] || 0;
|
|
158
|
+
if (p1 < p2) return -1;
|
|
159
|
+
if (p1 > p2) return 1;
|
|
160
|
+
}
|
|
161
|
+
return 0;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
exports.checkUpdate = checkUpdate;
|
|
165
|
+
exports.getCurrentVersion = getCurrentVersion;
|
|
166
|
+
exports.compareVersions = compareVersions;
|
|
167
|
+
exports.getLastCheckTime = getLastCheckTime;
|
|
168
|
+
exports.saveLastCheckTime = saveLastCheckTime;
|
|
169
|
+
exports.CURRENT_VERSION = CURRENT_VERSION;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sumulige-claude",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "The Best Agent Harness for Claude Code",
|
|
5
5
|
"main": "cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,11 +8,17 @@
|
|
|
8
8
|
"sumulige-claude": "cli.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"test": "
|
|
11
|
+
"test": "jest",
|
|
12
|
+
"test:coverage": "jest --coverage",
|
|
13
|
+
"test:watch": "jest --watch",
|
|
12
14
|
"postinstall": "node cli.js init",
|
|
13
15
|
"sync": "node scripts/sync-external.mjs",
|
|
14
16
|
"update-registry": "node scripts/update-registry.mjs",
|
|
15
|
-
"sync:all": "npm run sync && npm run update-registry"
|
|
17
|
+
"sync:all": "npm run sync && npm run update-registry",
|
|
18
|
+
"release": "standard-version",
|
|
19
|
+
"release:patch": "standard-version --release-as patch",
|
|
20
|
+
"release:minor": "standard-version --release-as minor",
|
|
21
|
+
"release:major": "standard-version --release-as major"
|
|
16
22
|
},
|
|
17
23
|
"keywords": [
|
|
18
24
|
"claude",
|
|
@@ -35,7 +41,11 @@
|
|
|
35
41
|
"node": ">=16.0.0"
|
|
36
42
|
},
|
|
37
43
|
"devDependencies": {
|
|
44
|
+
"jest": "^30.2.0",
|
|
45
|
+
"mock-fs": "^5.5.0",
|
|
38
46
|
"prettier": "^3.7.4",
|
|
47
|
+
"sinon": "^21.0.1",
|
|
48
|
+
"standard-version": "^9.5.0",
|
|
39
49
|
"yaml": "^2.8.2"
|
|
40
50
|
}
|
|
41
51
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Fix hooks format from old to new
|
|
4
|
+
* 旧格式:{"matcher": "...", "hooks": [...]}
|
|
5
|
+
* 新格式:{"UserPromptSubmit": [{"matcher": {}, "hooks": [...]}], ...}
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
|
|
11
|
+
const NEW_FORMAT = {
|
|
12
|
+
"UserPromptSubmit": [
|
|
13
|
+
{
|
|
14
|
+
"matcher": {},
|
|
15
|
+
"hooks": [
|
|
16
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/project-kickoff.cjs", "timeout": 1000 },
|
|
17
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/rag-skill-loader.cjs", "timeout": 1000 },
|
|
18
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs", "timeout": 1000 },
|
|
19
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs", "timeout": 1000 },
|
|
20
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs", "timeout": 1000 }
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"PreToolUse": [
|
|
25
|
+
{
|
|
26
|
+
"matcher": {},
|
|
27
|
+
"hooks": [
|
|
28
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs", "timeout": 1000 },
|
|
29
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs", "timeout": 1000 },
|
|
30
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs", "timeout": 1000 }
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"PostToolUse": [
|
|
35
|
+
{
|
|
36
|
+
"matcher": {},
|
|
37
|
+
"hooks": [
|
|
38
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/code-formatter.cjs", "timeout": 5000 },
|
|
39
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/verify-work.cjs", "timeout": 1000 },
|
|
40
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs", "timeout": 1000 },
|
|
41
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs", "timeout": 1000 },
|
|
42
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs", "timeout": 1000 }
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"AgentStop": [
|
|
47
|
+
{
|
|
48
|
+
"matcher": {},
|
|
49
|
+
"hooks": [
|
|
50
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/verify-work.cjs", "timeout": 1000 },
|
|
51
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs", "timeout": 1000 },
|
|
52
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs", "timeout": 1000 },
|
|
53
|
+
{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs", "timeout": 1000 }
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
function fixProject(projectPath) {
|
|
60
|
+
const settingsFile = path.join(projectPath, '.claude', 'settings.json');
|
|
61
|
+
|
|
62
|
+
if (!fs.existsSync(settingsFile)) {
|
|
63
|
+
console.log(`⚠️ ${projectPath} - no settings.json`);
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let settings;
|
|
68
|
+
try {
|
|
69
|
+
settings = JSON.parse(fs.readFileSync(settingsFile, 'utf-8'));
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.log(`❌ ${projectPath} - invalid JSON`);
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 检测旧格式
|
|
76
|
+
const isOldFormat = settings.matcher || (settings.hooks && typeof settings.hooks === 'object');
|
|
77
|
+
|
|
78
|
+
if (!isOldFormat) {
|
|
79
|
+
console.log(`✅ ${projectPath} - already new format`);
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 写入新格式
|
|
84
|
+
fs.writeFileSync(settingsFile, JSON.stringify(NEW_FORMAT, null, 2) + '\n');
|
|
85
|
+
console.log(`🔧 ${projectPath} - fixed!`);
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// CLI
|
|
90
|
+
const args = process.argv.slice(2);
|
|
91
|
+
|
|
92
|
+
if (args.length === 0) {
|
|
93
|
+
// 当前目录
|
|
94
|
+
fixProject(process.cwd());
|
|
95
|
+
} else {
|
|
96
|
+
args.forEach(fixProject);
|
|
97
|
+
}
|
|
@@ -22,7 +22,27 @@ Analyze the changes and:
|
|
|
22
22
|
2. Identify the main purpose of the changes
|
|
23
23
|
3. Check if there are any sensitive files that shouldn't be committed
|
|
24
24
|
|
|
25
|
-
## Step 3:
|
|
25
|
+
## Step 3: Code Simplification (Before Commit)
|
|
26
|
+
|
|
27
|
+
**IMPORTANT**: Before creating the commit, simplify and refine the code changes:
|
|
28
|
+
|
|
29
|
+
1. Review the recently modified code sections
|
|
30
|
+
2. Apply code simplification focusing on:
|
|
31
|
+
- Code clarity and consistency
|
|
32
|
+
- Reducing unnecessary complexity and nesting
|
|
33
|
+
- Eliminating redundant code and abstractions
|
|
34
|
+
- Following project standards (if CLAUDE.md exists)
|
|
35
|
+
- Preserving exact functionality
|
|
36
|
+
3. Use explicit, readable code over overly compact solutions
|
|
37
|
+
|
|
38
|
+
**Trigger phrases to apply simplification**:
|
|
39
|
+
- "简化此代码" (Simplify this code)
|
|
40
|
+
- "使这更清晰" (Make this clearer)
|
|
41
|
+
- "优化此实现" (Optimize this implementation)
|
|
42
|
+
|
|
43
|
+
Ask the user: "是否需要简化代码?(Need code simplification?)" - if yes, apply code-simplifier agent before proceeding.
|
|
44
|
+
|
|
45
|
+
## Step 4: Stage and Commit
|
|
26
46
|
|
|
27
47
|
If there are unstaged changes that should be included, ask the user first.
|
|
28
48
|
|
|
@@ -36,7 +56,7 @@ Then create a commit with a clear message following this format:
|
|
|
36
56
|
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
37
57
|
```
|
|
38
58
|
|
|
39
|
-
## Step
|
|
59
|
+
## Step 5: Push and Create PR
|
|
40
60
|
|
|
41
61
|
1. Push the changes to remote
|
|
42
62
|
2. Check if there's an open PR for this branch using:
|
|
@@ -51,7 +71,7 @@ Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
|
51
71
|
- Test plan (checklist)
|
|
52
72
|
- Link to any related issues
|
|
53
73
|
|
|
54
|
-
## Step
|
|
74
|
+
## Step 6: Verify
|
|
55
75
|
|
|
56
76
|
After creating the PR, show the PR URL and check CI status using:
|
|
57
77
|
```bash
|