@thanhvn14/csvibe 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/agents/schemas/base-output.schema.json +88 -0
- package/.github/agents/schemas/brainstorm-output.schema.json +88 -0
- package/.github/agents/schemas/scout-output.schema.json +60 -0
- package/.github/agents/scripts/fetch-copilot-tools.js +245 -0
- package/.github/agents/scripts/lib/parse-agent-file.js +275 -0
- package/.github/agents/scripts/package-lock.json +78 -0
- package/.github/agents/scripts/package.json +22 -0
- package/.github/agents/scripts/schemas/agent-frontmatter.schema.json +83 -0
- package/.github/agents/scripts/validate-agent-all.js +157 -0
- package/.github/agents/scripts/validate-agent-frontmatter.js +96 -0
- package/.github/agents/scripts/validate-agent-handoffs.js +169 -0
- package/.github/agents/scripts/validate-agent-output.js +157 -0
- package/.github/agents/scripts/validate-agent-tools.js +278 -0
- package/.github/skills/.env.example +100 -0
- package/.github/skills/.install-state.json +23 -0
- package/.github/skills/README.md +149 -0
- package/.github/skills/ai-multimodal/.env.example +204 -0
- package/.github/skills/ai-multimodal/scripts/.coverage +0 -0
- package/.github/skills/ai-multimodal/scripts/check_setup.py +305 -0
- package/.github/skills/ai-multimodal/scripts/document_converter.py +395 -0
- package/.github/skills/ai-multimodal/scripts/gemini_batch_process.py +1184 -0
- package/.github/skills/ai-multimodal/scripts/media_optimizer.py +506 -0
- package/.github/skills/ai-multimodal/scripts/requirements.txt +26 -0
- package/.github/skills/better-auth/scripts/.coverage +0 -0
- package/.github/skills/better-auth/scripts/better_auth_init.py +521 -0
- package/.github/skills/better-auth/scripts/requirements.txt +15 -0
- package/.github/skills/chrome-devtools/scripts/README.md +272 -0
- package/.github/skills/chrome-devtools/scripts/__tests__/selector.test.js +210 -0
- package/.github/skills/chrome-devtools/scripts/aria-snapshot.js +362 -0
- package/.github/skills/chrome-devtools/scripts/click.js +83 -0
- package/.github/skills/chrome-devtools/scripts/console.js +79 -0
- package/.github/skills/chrome-devtools/scripts/evaluate.js +53 -0
- package/.github/skills/chrome-devtools/scripts/fill.js +76 -0
- package/.github/skills/chrome-devtools/scripts/inject-auth.js +229 -0
- package/.github/skills/chrome-devtools/scripts/install-deps.sh +181 -0
- package/.github/skills/chrome-devtools/scripts/install.sh +83 -0
- package/.github/skills/chrome-devtools/scripts/lib/browser.js +318 -0
- package/.github/skills/chrome-devtools/scripts/lib/selector.js +178 -0
- package/.github/skills/chrome-devtools/scripts/navigate.js +54 -0
- package/.github/skills/chrome-devtools/scripts/network.js +106 -0
- package/.github/skills/chrome-devtools/scripts/package-lock.json +1589 -0
- package/.github/skills/chrome-devtools/scripts/package.json +16 -0
- package/.github/skills/chrome-devtools/scripts/performance.js +149 -0
- package/.github/skills/chrome-devtools/scripts/screenshot.js +198 -0
- package/.github/skills/chrome-devtools/scripts/select-ref.js +131 -0
- package/.github/skills/chrome-devtools/scripts/snapshot.js +135 -0
- package/.github/skills/common/README.md +120 -0
- package/.github/skills/common/api_key_helper.py +411 -0
- package/.github/skills/common/api_key_rotator.py +248 -0
- package/.github/skills/databases/scripts/.coverage +0 -0
- package/.github/skills/databases/scripts/db_backup.py +502 -0
- package/.github/skills/databases/scripts/db_migrate.py +425 -0
- package/.github/skills/databases/scripts/db_performance_check.py +456 -0
- package/.github/skills/databases/scripts/requirements.txt +20 -0
- package/.github/skills/debugging/scripts/find-polluter.sh +63 -0
- package/.github/skills/devops/.env.example +76 -0
- package/.github/skills/devops/scripts/cloudflare_deploy.py +269 -0
- package/.github/skills/devops/scripts/docker_optimize.py +331 -0
- package/.github/skills/devops/scripts/requirements.txt +20 -0
- package/.github/skills/docs-seeker/.env.example +15 -0
- package/.github/skills/docs-seeker/package.json +25 -0
- package/.github/skills/docs-seeker/scripts/analyze-llms-txt.js +211 -0
- package/.github/skills/docs-seeker/scripts/detect-topic.js +172 -0
- package/.github/skills/docs-seeker/scripts/fetch-docs.js +213 -0
- package/.github/skills/docs-seeker/scripts/utils/env-loader.js +94 -0
- package/.github/skills/document-skills/docx/LICENSE.txt +30 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.github/skills/document-skills/docx/ooxml/scripts/pack.py +159 -0
- package/.github/skills/document-skills/docx/ooxml/scripts/unpack.py +29 -0
- package/.github/skills/document-skills/docx/ooxml/scripts/validate.py +69 -0
- package/.github/skills/document-skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/.github/skills/document-skills/docx/ooxml/scripts/validation/base.py +951 -0
- package/.github/skills/document-skills/docx/ooxml/scripts/validation/docx.py +274 -0
- package/.github/skills/document-skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/.github/skills/document-skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/.github/skills/document-skills/docx/scripts/__init__.py +1 -0
- package/.github/skills/document-skills/docx/scripts/document.py +1276 -0
- package/.github/skills/document-skills/docx/scripts/templates/comments.xml +3 -0
- package/.github/skills/document-skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/.github/skills/document-skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/.github/skills/document-skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/.github/skills/document-skills/docx/scripts/templates/people.xml +3 -0
- package/.github/skills/document-skills/docx/scripts/utilities.py +374 -0
- package/.github/skills/document-skills/pdf/LICENSE.txt +30 -0
- package/.github/skills/document-skills/pdf/scripts/check_bounding_boxes.py +70 -0
- package/.github/skills/document-skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/.github/skills/document-skills/pdf/scripts/check_fillable_fields.py +12 -0
- package/.github/skills/document-skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/.github/skills/document-skills/pdf/scripts/create_validation_image.py +41 -0
- package/.github/skills/document-skills/pdf/scripts/extract_form_field_info.py +152 -0
- package/.github/skills/document-skills/pdf/scripts/fill_fillable_fields.py +114 -0
- package/.github/skills/document-skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/.github/skills/document-skills/pptx/LICENSE.txt +30 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.github/skills/document-skills/pptx/ooxml/scripts/pack.py +159 -0
- package/.github/skills/document-skills/pptx/ooxml/scripts/unpack.py +29 -0
- package/.github/skills/document-skills/pptx/ooxml/scripts/validate.py +69 -0
- package/.github/skills/document-skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/.github/skills/document-skills/pptx/ooxml/scripts/validation/base.py +951 -0
- package/.github/skills/document-skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/.github/skills/document-skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/.github/skills/document-skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/.github/skills/document-skills/pptx/scripts/html2pptx.js +979 -0
- package/.github/skills/document-skills/pptx/scripts/inventory.py +1020 -0
- package/.github/skills/document-skills/pptx/scripts/rearrange.py +231 -0
- package/.github/skills/document-skills/pptx/scripts/replace.py +385 -0
- package/.github/skills/document-skills/pptx/scripts/thumbnail.py +450 -0
- package/.github/skills/document-skills/xlsx/LICENSE.txt +30 -0
- package/.github/skills/document-skills/xlsx/recalc.py +190 -0
- package/.github/skills/install.ps1 +1220 -0
- package/.github/skills/install.sh +1032 -0
- package/.github/skills/markdown-novel-viewer/assets/directory-browser.css +215 -0
- package/.github/skills/markdown-novel-viewer/assets/favicon.png +0 -0
- package/.github/skills/markdown-novel-viewer/assets/novel-theme.css +818 -0
- package/.github/skills/markdown-novel-viewer/assets/reader.js +262 -0
- package/.github/skills/markdown-novel-viewer/assets/template.html +80 -0
- package/.github/skills/markdown-novel-viewer/package-lock.json +146 -0
- package/.github/skills/markdown-novel-viewer/package.json +15 -0
- package/.github/skills/markdown-novel-viewer/scripts/lib/http-server.cjs +434 -0
- package/.github/skills/markdown-novel-viewer/scripts/lib/markdown-renderer.cjs +272 -0
- package/.github/skills/markdown-novel-viewer/scripts/lib/plan-navigator.cjs +509 -0
- package/.github/skills/markdown-novel-viewer/scripts/lib/port-finder.cjs +48 -0
- package/.github/skills/markdown-novel-viewer/scripts/lib/process-mgr.cjs +150 -0
- package/.github/skills/markdown-novel-viewer/scripts/server.cjs +411 -0
- package/.github/skills/mcp-builder/LICENSE.txt +202 -0
- package/.github/skills/mcp-builder/scripts/connections.py +151 -0
- package/.github/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/.github/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/.github/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/.github/skills/mcp-management/README.md +219 -0
- package/.github/skills/mcp-management/assets/tools.json +3146 -0
- package/.github/skills/mcp-management/package-lock.json +6 -0
- package/.github/skills/mcp-management/scripts/.env.example +10 -0
- package/.github/skills/mcp-management/scripts/cli.ts +195 -0
- package/.github/skills/mcp-management/scripts/dist/analyze-tools.js +70 -0
- package/.github/skills/mcp-management/scripts/dist/cli.js +160 -0
- package/.github/skills/mcp-management/scripts/dist/mcp-client.js +183 -0
- package/.github/skills/mcp-management/scripts/mcp-client.ts +230 -0
- package/.github/skills/mcp-management/scripts/package.json +20 -0
- package/.github/skills/media-processing/scripts/README.md +111 -0
- package/.github/skills/media-processing/scripts/batch-remove-background.sh +124 -0
- package/.github/skills/media-processing/scripts/batch_resize.py +342 -0
- package/.github/skills/media-processing/scripts/media_convert.py +311 -0
- package/.github/skills/media-processing/scripts/remove-background.sh +96 -0
- package/.github/skills/media-processing/scripts/remove-bg-node.js +158 -0
- package/.github/skills/media-processing/scripts/requirements.txt +24 -0
- package/.github/skills/media-processing/scripts/video_optimize.py +414 -0
- package/.github/skills/payment-integration/README.md +185 -0
- package/.github/skills/payment-integration/scripts/.env.example +20 -0
- package/.github/skills/payment-integration/scripts/checkout-helper.js +244 -0
- package/.github/skills/payment-integration/scripts/package.json +17 -0
- package/.github/skills/payment-integration/scripts/polar-webhook-verify.js +202 -0
- package/.github/skills/payment-integration/scripts/sepay-webhook-verify.js +193 -0
- package/.github/skills/payment-integration/scripts/test-scripts.js +237 -0
- package/.github/skills/plans-kanban/assets/dashboard-template.html +119 -0
- package/.github/skills/plans-kanban/assets/dashboard.css +1594 -0
- package/.github/skills/plans-kanban/assets/dashboard.js +596 -0
- package/.github/skills/plans-kanban/assets/favicon.png +0 -0
- package/.github/skills/plans-kanban/package-lock.json +123 -0
- package/.github/skills/plans-kanban/package.json +13 -0
- package/.github/skills/plans-kanban/scripts/lib/dashboard-renderer.cjs +884 -0
- package/.github/skills/plans-kanban/scripts/lib/http-server.cjs +310 -0
- package/.github/skills/plans-kanban/scripts/lib/plan-metadata-extractor.cjs +489 -0
- package/.github/skills/plans-kanban/scripts/lib/plan-parser.cjs +175 -0
- package/.github/skills/plans-kanban/scripts/lib/plan-scanner.cjs +272 -0
- package/.github/skills/plans-kanban/scripts/lib/port-finder.cjs +48 -0
- package/.github/skills/plans-kanban/scripts/lib/process-mgr.cjs +128 -0
- package/.github/skills/plans-kanban/scripts/server.cjs +260 -0
- package/.github/skills/repomix/scripts/.coverage +0 -0
- package/.github/skills/repomix/scripts/README.md +179 -0
- package/.github/skills/repomix/scripts/repomix_batch.py +455 -0
- package/.github/skills/repomix/scripts/repos.example.json +15 -0
- package/.github/skills/repomix/scripts/requirements.txt +15 -0
- package/.github/skills/scout-validation/scripts/lib/broad-pattern-detector.cjs +124 -0
- package/.github/skills/scout-validation/scripts/lib/path-checker.cjs +66 -0
- package/.github/skills/scout-validation/scripts/lib/schema-validator.cjs +45 -0
- package/.github/skills/scout-validation/scripts/package.json +11 -0
- package/.github/skills/scout-validation/scripts/validate-scout-output.cjs +219 -0
- package/.github/skills/scout-validation/test/broad-pattern-output.json +18 -0
- package/.github/skills/scout-validation/test/invalid-path-output.json +18 -0
- package/.github/skills/scout-validation/test/valid-scout-output.json +26 -0
- package/.github/skills/sequential-thinking/.env.example +8 -0
- package/.github/skills/sequential-thinking/README.md +183 -0
- package/.github/skills/sequential-thinking/package.json +31 -0
- package/.github/skills/sequential-thinking/scripts/format-thought.js +159 -0
- package/.github/skills/sequential-thinking/scripts/process-thought.js +236 -0
- package/.github/skills/shopify/README.md +66 -0
- package/.github/skills/shopify/scripts/.coverage +0 -0
- package/.github/skills/shopify/scripts/requirements.txt +19 -0
- package/.github/skills/shopify/scripts/shopify_init.py +423 -0
- package/.github/skills/skill-creator/LICENSE.txt +202 -0
- package/.github/skills/skill-creator/scripts/init_skill.py +303 -0
- package/.github/skills/skill-creator/scripts/package_skill.py +110 -0
- package/.github/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/.github/skills/ui-styling/LICENSE.txt +202 -0
- package/.github/skills/ui-styling/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/DMMono-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/.github/skills/ui-styling/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Gloock-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Italiana-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Jura-Light.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Jura-Medium.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Jura-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Lora-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Lora-Italic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Lora-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/Lora-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Outfit-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/Tektur-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/.github/skills/ui-styling/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/.github/skills/ui-styling/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/.github/skills/ui-styling/scripts/.coverage +0 -0
- package/.github/skills/ui-styling/scripts/requirements.txt +17 -0
- package/.github/skills/ui-styling/scripts/shadcn_add.py +292 -0
- package/.github/skills/ui-styling/scripts/tailwind_config_gen.py +456 -0
- package/.github/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.github/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.github/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.github/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.github/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.github/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.github/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +51 -0
- package/.github/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.github/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.github/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.github/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.github/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.github/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.github/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/.github/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.github/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.github/skills/ui-ux-pro-max/scripts/core.py +236 -0
- package/.github/skills/ui-ux-pro-max/scripts/search.py +76 -0
- package/.github/skills/web-frameworks/scripts/.coverage +0 -0
- package/.github/skills/web-frameworks/scripts/__init__.py +0 -0
- package/.github/skills/web-frameworks/scripts/nextjs_init.py +547 -0
- package/.github/skills/web-frameworks/scripts/requirements.txt +16 -0
- package/.github/skills/web-frameworks/scripts/turborepo_migrate.py +394 -0
- package/dist/config/constants.d.ts +3 -0
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +5 -1
- package/dist/config/constants.js.map +1 -1
- package/dist/domains/github/github-client.d.ts +5 -0
- package/dist/domains/github/github-client.d.ts.map +1 -1
- package/dist/domains/github/github-client.js +44 -0
- package/dist/domains/github/github-client.js.map +1 -1
- package/dist/utils/downloader.d.ts +3 -1
- package/dist/utils/downloader.d.ts.map +1 -1
- package/dist/utils/downloader.js +48 -11
- package/dist/utils/downloader.js.map +1 -1
- package/dist/utils/scaffolder.d.ts.map +1 -1
- package/dist/utils/scaffolder.js +2 -0
- package/dist/utils/scaffolder.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,1032 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Skills Installation Script for Linux/macOS
|
|
3
|
+
# Installs all dependencies for Claude Code skills
|
|
4
|
+
#
|
|
5
|
+
# Exit codes (rustup model):
|
|
6
|
+
# 0 = Success (full or partial)
|
|
7
|
+
# 1 = Fatal error (no Python, broken venv)
|
|
8
|
+
# 2 = Partial success (some optional deps failed)
|
|
9
|
+
|
|
10
|
+
# set -e removed - we handle errors per-phase
|
|
11
|
+
|
|
12
|
+
# Parse command line arguments
|
|
13
|
+
SKIP_CONFIRM=false
|
|
14
|
+
WITH_SUDO=false
|
|
15
|
+
RESUME_MODE=false
|
|
16
|
+
RETRY_FAILED=false
|
|
17
|
+
while [[ "$#" -gt 0 ]]; do
|
|
18
|
+
case $1 in
|
|
19
|
+
-y|--yes) SKIP_CONFIRM=true ;;
|
|
20
|
+
--with-sudo) WITH_SUDO=true ;;
|
|
21
|
+
--resume) RESUME_MODE=true ;;
|
|
22
|
+
--retry-failed) RETRY_FAILED=true ;;
|
|
23
|
+
*) echo "Unknown parameter: $1"; exit 1 ;;
|
|
24
|
+
esac
|
|
25
|
+
shift
|
|
26
|
+
done
|
|
27
|
+
|
|
28
|
+
# Check for NON_INTERACTIVE environment variable
|
|
29
|
+
if [[ -n "${NON_INTERACTIVE}" ]]; then
|
|
30
|
+
SKIP_CONFIRM=true
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Colors for output
|
|
34
|
+
RED='\033[0;31m'
|
|
35
|
+
GREEN='\033[0;32m'
|
|
36
|
+
YELLOW='\033[1;33m'
|
|
37
|
+
BLUE='\033[0;34m'
|
|
38
|
+
NC='\033[0m' # No Color
|
|
39
|
+
|
|
40
|
+
# Configuration
|
|
41
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
42
|
+
VENV_DIR="$SCRIPT_DIR/.venv"
|
|
43
|
+
STATE_FILE="$SCRIPT_DIR/.install-state.json"
|
|
44
|
+
LOG_DIR="$VENV_DIR/logs"
|
|
45
|
+
|
|
46
|
+
# Installation tracking arrays (Bash 3.2+ compatible - indexed arrays only)
|
|
47
|
+
declare -a INSTALLED_CRITICAL=()
|
|
48
|
+
declare -a INSTALLED_OPTIONAL=()
|
|
49
|
+
declare -a FAILED_OPTIONAL=()
|
|
50
|
+
declare -a SKIPPED_SUDO=()
|
|
51
|
+
FINAL_EXIT_CODE=0
|
|
52
|
+
|
|
53
|
+
# Detect OS
|
|
54
|
+
detect_os() {
|
|
55
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
56
|
+
echo "macos"
|
|
57
|
+
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
58
|
+
echo "linux"
|
|
59
|
+
else
|
|
60
|
+
echo "unknown"
|
|
61
|
+
fi
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# Print functions (must be defined before check_bash_version)
|
|
65
|
+
print_header() {
|
|
66
|
+
echo -e "\n${BLUE}===================================================${NC}"
|
|
67
|
+
echo -e "${BLUE}$1${NC}"
|
|
68
|
+
echo -e "${BLUE}===================================================${NC}\n"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
print_success() {
|
|
72
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
print_warning() {
|
|
76
|
+
echo -e "${YELLOW}⚠${NC} $1"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
print_error() {
|
|
80
|
+
echo -e "${RED}✗${NC} $1"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
print_info() {
|
|
84
|
+
echo -e "${BLUE}ℹ${NC} $1"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Check Bash version (3.2+ required for compatibility)
|
|
88
|
+
check_bash_version() {
|
|
89
|
+
# Get major version number
|
|
90
|
+
bash_major="${BASH_VERSINFO[0]}"
|
|
91
|
+
|
|
92
|
+
if [ "$bash_major" -lt 3 ]; then
|
|
93
|
+
print_error "Bash 3.0+ required (found Bash $BASH_VERSION)"
|
|
94
|
+
print_info "Please upgrade Bash and re-run this script"
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
if [ "$bash_major" -lt 4 ]; then
|
|
99
|
+
print_warning "Bash 3.x detected (Bash 4+ recommended)"
|
|
100
|
+
|
|
101
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
102
|
+
print_info "macOS ships with Bash 3.2 by default"
|
|
103
|
+
print_info "For better compatibility: brew install bash"
|
|
104
|
+
print_info "Then use: /usr/local/bin/bash install.sh"
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
print_info "Continuing with compatibility mode..."
|
|
108
|
+
fi
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
OS=$(detect_os)
|
|
112
|
+
check_bash_version
|
|
113
|
+
|
|
114
|
+
# Check if command exists
|
|
115
|
+
command_exists() {
|
|
116
|
+
command -v "$1" >/dev/null 2>&1
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# ============================================================================
|
|
120
|
+
# Installation Tracking Functions
|
|
121
|
+
# ============================================================================
|
|
122
|
+
|
|
123
|
+
track_success() {
|
|
124
|
+
local category="$1" name="$2"
|
|
125
|
+
if [[ "$category" == "critical" ]]; then
|
|
126
|
+
INSTALLED_CRITICAL+=("$name")
|
|
127
|
+
else
|
|
128
|
+
INSTALLED_OPTIONAL+=("$name")
|
|
129
|
+
fi
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
track_failure() {
|
|
133
|
+
local category="$1" name="$2" reason="$3"
|
|
134
|
+
if [[ "$category" == "critical" ]]; then
|
|
135
|
+
FINAL_EXIT_CODE=1
|
|
136
|
+
else
|
|
137
|
+
FAILED_OPTIONAL+=("$name: $reason")
|
|
138
|
+
[[ "$FINAL_EXIT_CODE" == "0" ]] && FINAL_EXIT_CODE=2
|
|
139
|
+
fi
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
track_skipped() {
|
|
143
|
+
local name="$1" reason="$2"
|
|
144
|
+
SKIPPED_SUDO+=("$name: $reason")
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# ============================================================================
|
|
148
|
+
# State Persistence Functions
|
|
149
|
+
# ============================================================================
|
|
150
|
+
|
|
151
|
+
# Initialize or load state
|
|
152
|
+
init_state() {
|
|
153
|
+
if [[ "$RESUME_MODE" == "true" ]] && [[ -f "$STATE_FILE" ]]; then
|
|
154
|
+
print_info "Resuming from previous installation..."
|
|
155
|
+
return 0
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
# Create fresh state
|
|
159
|
+
cat > "$STATE_FILE" << EOF
|
|
160
|
+
{
|
|
161
|
+
"version": 1,
|
|
162
|
+
"started_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
163
|
+
"last_updated": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
164
|
+
"phases": {
|
|
165
|
+
"system_deps": "pending",
|
|
166
|
+
"node_deps": "pending",
|
|
167
|
+
"python_env": "pending",
|
|
168
|
+
"verify": "pending"
|
|
169
|
+
},
|
|
170
|
+
"packages": {
|
|
171
|
+
"installed": [],
|
|
172
|
+
"failed": [],
|
|
173
|
+
"skipped": []
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
EOF
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
# Update phase status
|
|
180
|
+
update_phase() {
|
|
181
|
+
local phase="$1" status="$2"
|
|
182
|
+
if [[ ! -f "$STATE_FILE" ]]; then
|
|
183
|
+
return 0
|
|
184
|
+
fi
|
|
185
|
+
local temp_file="$STATE_FILE.tmp"
|
|
186
|
+
|
|
187
|
+
# Simple sed replacement (jq not required)
|
|
188
|
+
sed "s/\"$phase\": \"[^\"]*\"/\"$phase\": \"$status\"/" "$STATE_FILE" > "$temp_file"
|
|
189
|
+
mv "$temp_file" "$STATE_FILE"
|
|
190
|
+
|
|
191
|
+
# Update timestamp
|
|
192
|
+
sed "s/\"last_updated\": \"[^\"]*\"/\"last_updated\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"/" "$STATE_FILE" > "$temp_file"
|
|
193
|
+
mv "$temp_file" "$STATE_FILE"
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# Check if phase is already done (for resume)
|
|
197
|
+
phase_done() {
|
|
198
|
+
local phase="$1"
|
|
199
|
+
grep -q "\"$phase\": \"done\"" "$STATE_FILE" 2>/dev/null
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
# Clean state file (on complete success)
|
|
203
|
+
clean_state() {
|
|
204
|
+
if [[ -f "$STATE_FILE" ]]; then
|
|
205
|
+
rm -f "$STATE_FILE"
|
|
206
|
+
print_info "Installation state cleaned (success)"
|
|
207
|
+
fi
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
# ============================================================================
|
|
211
|
+
# Build Tools Detection
|
|
212
|
+
# ============================================================================
|
|
213
|
+
|
|
214
|
+
# Check if system has C build tools for compiling Python packages
|
|
215
|
+
has_build_tools() {
|
|
216
|
+
if command_exists gcc || command_exists clang; then
|
|
217
|
+
if [[ "$OS" == "linux" ]]; then
|
|
218
|
+
# Check for Python dev headers
|
|
219
|
+
if [[ -f /usr/include/python3*/Python.h ]] || \
|
|
220
|
+
python3-config --includes &>/dev/null; then
|
|
221
|
+
return 0
|
|
222
|
+
fi
|
|
223
|
+
elif [[ "$OS" == "macos" ]]; then
|
|
224
|
+
# macOS: Xcode command line tools include headers
|
|
225
|
+
if xcode-select -p &>/dev/null; then
|
|
226
|
+
return 0
|
|
227
|
+
fi
|
|
228
|
+
fi
|
|
229
|
+
fi
|
|
230
|
+
return 1
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
# Try pip install with wheel-first fallback
|
|
234
|
+
# Returns: 0=success, 1=failed
|
|
235
|
+
try_pip_install() {
|
|
236
|
+
local package_spec="$1"
|
|
237
|
+
local log_file="$2"
|
|
238
|
+
local package_name="${package_spec%%[=<>]*}" # Strip version specifier
|
|
239
|
+
|
|
240
|
+
# Phase 1: Try with prefer-binary (wheels first)
|
|
241
|
+
if pip install "$package_spec" --prefer-binary 2>&1 | tee -a "$log_file"; then
|
|
242
|
+
return 0
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# Phase 2: Check if we can build from source
|
|
246
|
+
if ! has_build_tools; then
|
|
247
|
+
print_warning "$package_name: No wheel available, no build tools"
|
|
248
|
+
if [[ "$OS" == "linux" ]]; then
|
|
249
|
+
print_info "Install build tools: sudo apt-get install gcc python3-dev"
|
|
250
|
+
elif [[ "$OS" == "macos" ]]; then
|
|
251
|
+
print_info "Install build tools: xcode-select --install"
|
|
252
|
+
fi
|
|
253
|
+
return 1
|
|
254
|
+
fi
|
|
255
|
+
|
|
256
|
+
# Phase 3: Try source build
|
|
257
|
+
print_info "Trying source build for $package_name..."
|
|
258
|
+
if pip install "$package_spec" --no-binary "$package_name" 2>&1 | tee -a "$log_file"; then
|
|
259
|
+
print_success "$package_name installed (source build)"
|
|
260
|
+
return 0
|
|
261
|
+
fi
|
|
262
|
+
|
|
263
|
+
print_error "$package_name: Both wheel and source build failed"
|
|
264
|
+
return 1
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
# Install system package - no prompts, just install or skip
|
|
268
|
+
# CLI controls sudo via --with-sudo flag
|
|
269
|
+
install_system_package() {
|
|
270
|
+
local package_name="$1"
|
|
271
|
+
local display_name="$2"
|
|
272
|
+
local check_commands="$3" # Comma-separated commands to check
|
|
273
|
+
|
|
274
|
+
# Check if already installed (check multiple commands)
|
|
275
|
+
IFS=',' read -ra cmds <<< "$check_commands"
|
|
276
|
+
for cmd in "${cmds[@]}"; do
|
|
277
|
+
if command_exists "$cmd"; then
|
|
278
|
+
print_success "$display_name already installed"
|
|
279
|
+
track_success "optional" "$display_name"
|
|
280
|
+
return 0
|
|
281
|
+
fi
|
|
282
|
+
done
|
|
283
|
+
|
|
284
|
+
# macOS: brew doesn't need sudo
|
|
285
|
+
if [[ "$OS" == "macos" ]]; then
|
|
286
|
+
print_info "Installing $display_name..."
|
|
287
|
+
if brew install "$package_name" 2>/dev/null; then
|
|
288
|
+
print_success "$display_name installed"
|
|
289
|
+
track_success "optional" "$display_name"
|
|
290
|
+
return 0
|
|
291
|
+
else
|
|
292
|
+
print_warning "$display_name: brew install failed"
|
|
293
|
+
track_failure "optional" "$display_name" "brew install failed"
|
|
294
|
+
return 1
|
|
295
|
+
fi
|
|
296
|
+
fi
|
|
297
|
+
|
|
298
|
+
# Linux: only install if --with-sudo was passed
|
|
299
|
+
if [[ "$WITH_SUDO" == "true" ]]; then
|
|
300
|
+
print_info "Installing $display_name (sudo)..."
|
|
301
|
+
if sudo apt-get install -y "$package_name"; then
|
|
302
|
+
print_success "$display_name installed"
|
|
303
|
+
track_success "optional" "$display_name"
|
|
304
|
+
return 0
|
|
305
|
+
else
|
|
306
|
+
print_warning "$display_name: apt-get install failed"
|
|
307
|
+
track_failure "optional" "$display_name" "apt-get install failed"
|
|
308
|
+
return 1
|
|
309
|
+
fi
|
|
310
|
+
else
|
|
311
|
+
# No sudo permission - track as skipped
|
|
312
|
+
print_info "$display_name: skipped (no --with-sudo)"
|
|
313
|
+
track_skipped "$display_name" "requires sudo"
|
|
314
|
+
return 0 # Don't fail, just skip
|
|
315
|
+
fi
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
# Check and install system package manager
|
|
319
|
+
check_package_manager() {
|
|
320
|
+
if [[ "$OS" == "macos" ]]; then
|
|
321
|
+
if ! command_exists brew; then
|
|
322
|
+
print_warning "Homebrew not found. Installing Homebrew..."
|
|
323
|
+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
324
|
+
print_success "Homebrew installed"
|
|
325
|
+
else
|
|
326
|
+
print_success "Homebrew found"
|
|
327
|
+
fi
|
|
328
|
+
elif [[ "$OS" == "linux" ]]; then
|
|
329
|
+
if command_exists apt-get; then
|
|
330
|
+
print_success "apt-get found"
|
|
331
|
+
elif command_exists yum; then
|
|
332
|
+
print_success "yum found"
|
|
333
|
+
else
|
|
334
|
+
print_warning "No supported package manager found (apt-get or yum)"
|
|
335
|
+
print_info "System packages will be skipped"
|
|
336
|
+
# Don't exit - just warn and continue
|
|
337
|
+
fi
|
|
338
|
+
fi
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
# Install system dependencies
|
|
342
|
+
install_system_deps() {
|
|
343
|
+
print_header "Installing System Dependencies"
|
|
344
|
+
|
|
345
|
+
# Update apt cache if we have sudo permission (Linux only)
|
|
346
|
+
if [[ "$OS" == "linux" ]] && [[ "$WITH_SUDO" == "true" ]]; then
|
|
347
|
+
print_info "Updating package lists..."
|
|
348
|
+
sudo apt-get update -qq
|
|
349
|
+
fi
|
|
350
|
+
|
|
351
|
+
# FFmpeg (required for media-processing skill)
|
|
352
|
+
install_system_package "ffmpeg" "FFmpeg" "ffmpeg"
|
|
353
|
+
|
|
354
|
+
# ImageMagick (required for media-processing skill)
|
|
355
|
+
install_system_package "imagemagick" "ImageMagick" "magick,convert"
|
|
356
|
+
|
|
357
|
+
# PostgreSQL client (optional - just check)
|
|
358
|
+
if command_exists psql; then
|
|
359
|
+
print_success "PostgreSQL client already installed"
|
|
360
|
+
fi
|
|
361
|
+
|
|
362
|
+
# Docker (optional - just check)
|
|
363
|
+
if command_exists docker; then
|
|
364
|
+
print_success "Docker already installed ($(docker --version))"
|
|
365
|
+
fi
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
# Install Node.js and npm packages
|
|
369
|
+
install_node_deps() {
|
|
370
|
+
print_header "Installing Node.js Dependencies"
|
|
371
|
+
|
|
372
|
+
# Check Node.js
|
|
373
|
+
if command_exists node; then
|
|
374
|
+
NODE_VERSION=$(node --version)
|
|
375
|
+
print_success "Node.js already installed ($NODE_VERSION)"
|
|
376
|
+
else
|
|
377
|
+
print_info "Installing Node.js..."
|
|
378
|
+
if [[ "$OS" == "macos" ]]; then
|
|
379
|
+
brew install node
|
|
380
|
+
elif [[ "$OS" == "linux" ]]; then
|
|
381
|
+
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|
382
|
+
sudo apt-get install -y nodejs
|
|
383
|
+
fi
|
|
384
|
+
print_success "Node.js installed"
|
|
385
|
+
fi
|
|
386
|
+
|
|
387
|
+
# Install global npm packages
|
|
388
|
+
print_info "Installing global npm packages..."
|
|
389
|
+
|
|
390
|
+
# Package name to CLI command mapping (some packages have different CLI names)
|
|
391
|
+
# Using indexed array with colon-separated pairs for Bash 3.2+ compatibility
|
|
392
|
+
npm_packages=(
|
|
393
|
+
"rmbg-cli:rmbg"
|
|
394
|
+
"pnpm:pnpm"
|
|
395
|
+
"wrangler:wrangler"
|
|
396
|
+
"repomix:repomix"
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
for package_pair in "${npm_packages[@]}"; do
|
|
400
|
+
# Split "package:command" on colon
|
|
401
|
+
IFS=':' read -r package cmd <<< "$package_pair"
|
|
402
|
+
|
|
403
|
+
# Check CLI command first (handles standalone installs like brew, curl, etc.)
|
|
404
|
+
if command_exists "$cmd"; then
|
|
405
|
+
version=$("$cmd" --version 2>&1 | head -n1 || echo "available")
|
|
406
|
+
print_success "$package already installed ($version)"
|
|
407
|
+
# Fallback: check if installed via npm registry
|
|
408
|
+
elif npm list -g "$package" >/dev/null 2>&1; then
|
|
409
|
+
print_success "$package already installed via npm"
|
|
410
|
+
else
|
|
411
|
+
print_info "Installing $package..."
|
|
412
|
+
npm install -g "$package" 2>/dev/null || {
|
|
413
|
+
print_warning "Failed to install $package globally. Trying with sudo..."
|
|
414
|
+
sudo npm install -g "$package"
|
|
415
|
+
}
|
|
416
|
+
print_success "$package installed"
|
|
417
|
+
fi
|
|
418
|
+
done
|
|
419
|
+
|
|
420
|
+
# Install local npm packages for skills
|
|
421
|
+
print_info "Installing local npm packages for skills..."
|
|
422
|
+
|
|
423
|
+
# chrome-devtools
|
|
424
|
+
if [ -d "$SCRIPT_DIR/chrome-devtools/scripts" ] && [ -f "$SCRIPT_DIR/chrome-devtools/scripts/package.json" ]; then
|
|
425
|
+
print_info "Installing chrome-devtools dependencies..."
|
|
426
|
+
(cd "$SCRIPT_DIR/chrome-devtools/scripts" && npm install --quiet)
|
|
427
|
+
print_success "chrome-devtools dependencies installed"
|
|
428
|
+
fi
|
|
429
|
+
|
|
430
|
+
# sequential-thinking
|
|
431
|
+
if [ -d "$SCRIPT_DIR/sequential-thinking" ] && [ -f "$SCRIPT_DIR/sequential-thinking/package.json" ]; then
|
|
432
|
+
print_info "Installing sequential-thinking dependencies..."
|
|
433
|
+
(cd "$SCRIPT_DIR/sequential-thinking" && npm install --quiet)
|
|
434
|
+
print_success "sequential-thinking dependencies installed"
|
|
435
|
+
fi
|
|
436
|
+
|
|
437
|
+
# mcp-management
|
|
438
|
+
if [ -d "$SCRIPT_DIR/mcp-management/scripts" ] && [ -f "$SCRIPT_DIR/mcp-management/scripts/package.json" ]; then
|
|
439
|
+
print_info "Installing mcp-management dependencies..."
|
|
440
|
+
(cd "$SCRIPT_DIR/mcp-management/scripts" && npm install --quiet)
|
|
441
|
+
print_success "mcp-management dependencies installed"
|
|
442
|
+
fi
|
|
443
|
+
|
|
444
|
+
# markdown-novel-viewer (marked, highlight.js, gray-matter)
|
|
445
|
+
if [ -d "$SCRIPT_DIR/markdown-novel-viewer" ] && [ -f "$SCRIPT_DIR/markdown-novel-viewer/package.json" ]; then
|
|
446
|
+
print_info "Installing markdown-novel-viewer dependencies..."
|
|
447
|
+
(cd "$SCRIPT_DIR/markdown-novel-viewer" && npm install --quiet)
|
|
448
|
+
print_success "markdown-novel-viewer dependencies installed"
|
|
449
|
+
fi
|
|
450
|
+
|
|
451
|
+
# plans-kanban (gray-matter)
|
|
452
|
+
if [ -d "$SCRIPT_DIR/plans-kanban" ] && [ -f "$SCRIPT_DIR/plans-kanban/package.json" ]; then
|
|
453
|
+
print_info "Installing plans-kanban dependencies..."
|
|
454
|
+
(cd "$SCRIPT_DIR/plans-kanban" && npm install --quiet)
|
|
455
|
+
print_success "plans-kanban dependencies installed"
|
|
456
|
+
fi
|
|
457
|
+
|
|
458
|
+
# Optional: Shopify CLI (ask user unless auto-confirming)
|
|
459
|
+
if [ -d "$SCRIPT_DIR/shopify" ]; then
|
|
460
|
+
if [[ "$SKIP_CONFIRM" == "true" ]]; then
|
|
461
|
+
print_info "Skipping Shopify CLI installation (optional, use --yes to install all)"
|
|
462
|
+
else
|
|
463
|
+
read -p "Install Shopify CLI for Shopify skill? (y/N) " -n 1 -r
|
|
464
|
+
echo
|
|
465
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
466
|
+
print_info "Installing Shopify CLI..."
|
|
467
|
+
npm install -g @shopify/cli @shopify/theme 2>/dev/null || {
|
|
468
|
+
print_warning "Failed to install Shopify CLI globally. Trying with sudo..."
|
|
469
|
+
sudo npm install -g @shopify/cli @shopify/theme
|
|
470
|
+
}
|
|
471
|
+
print_success "Shopify CLI installed"
|
|
472
|
+
fi
|
|
473
|
+
fi
|
|
474
|
+
fi
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
# Setup Python virtual environment
|
|
478
|
+
setup_python_env() {
|
|
479
|
+
print_header "Setting Up Python Environment"
|
|
480
|
+
|
|
481
|
+
# Track successful and failed installations
|
|
482
|
+
local successful_skills=()
|
|
483
|
+
local failed_skills=()
|
|
484
|
+
|
|
485
|
+
# Check Python
|
|
486
|
+
if command_exists python3; then
|
|
487
|
+
PYTHON_VERSION=$(python3 --version)
|
|
488
|
+
PYTHON_PATH=$(which python3)
|
|
489
|
+
print_success "Python3 found ($PYTHON_VERSION)"
|
|
490
|
+
|
|
491
|
+
# Check for broken UV Python installation
|
|
492
|
+
if [[ "$PYTHON_PATH" == *"/.local/share/uv/"* ]]; then
|
|
493
|
+
# Verify UV Python works by testing venv creation
|
|
494
|
+
if ! python3 -c "import sys; sys.exit(0 if '/install' not in sys.base_prefix else 1)" 2>/dev/null; then
|
|
495
|
+
print_error "UV Python installation is broken (corrupted sys.base_prefix)"
|
|
496
|
+
print_info "Please reinstall Python using Homebrew:"
|
|
497
|
+
print_info " brew install python@3.12"
|
|
498
|
+
print_info " export PATH=\"/opt/homebrew/bin:\$PATH\""
|
|
499
|
+
print_info "Or fix UV Python:"
|
|
500
|
+
print_info " uv python uninstall 3.12"
|
|
501
|
+
print_info " uv python install 3.12"
|
|
502
|
+
exit 1
|
|
503
|
+
fi
|
|
504
|
+
fi
|
|
505
|
+
else
|
|
506
|
+
print_error "Python3 not found. Please install Python 3.7+"
|
|
507
|
+
exit 1
|
|
508
|
+
fi
|
|
509
|
+
|
|
510
|
+
# Create virtual environment (or recreate if corrupted)
|
|
511
|
+
create_venv() {
|
|
512
|
+
# Try normal venv creation first
|
|
513
|
+
if python3 -m venv "$VENV_DIR" 2>/dev/null; then
|
|
514
|
+
return 0
|
|
515
|
+
fi
|
|
516
|
+
|
|
517
|
+
# If ensurepip fails (common on macOS), create without pip and bootstrap manually
|
|
518
|
+
print_warning "Standard venv creation failed, trying without ensurepip..."
|
|
519
|
+
if python3 -m venv --without-pip "$VENV_DIR"; then
|
|
520
|
+
# Bootstrap pip manually with error handling
|
|
521
|
+
source "$VENV_DIR/bin/activate"
|
|
522
|
+
if ! curl -sS https://bootstrap.pypa.io/get-pip.py | python3; then
|
|
523
|
+
print_error "Failed to bootstrap pip (network issue or get-pip.py failed)"
|
|
524
|
+
deactivate
|
|
525
|
+
rm -rf "$VENV_DIR"
|
|
526
|
+
return 1
|
|
527
|
+
fi
|
|
528
|
+
deactivate
|
|
529
|
+
return 0
|
|
530
|
+
fi
|
|
531
|
+
|
|
532
|
+
return 1
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if [ -d "$VENV_DIR" ]; then
|
|
536
|
+
# Verify venv is valid by checking for activate script AND python executable
|
|
537
|
+
if [ -f "$VENV_DIR/bin/activate" ] && [ -x "$VENV_DIR/bin/python3" ]; then
|
|
538
|
+
print_success "Virtual environment already exists at $VENV_DIR"
|
|
539
|
+
else
|
|
540
|
+
print_warning "Virtual environment is corrupted (missing activate or python3). Recreating..."
|
|
541
|
+
rm -rf "$VENV_DIR"
|
|
542
|
+
if create_venv; then
|
|
543
|
+
print_success "Virtual environment recreated"
|
|
544
|
+
else
|
|
545
|
+
print_error "Failed to create virtual environment"
|
|
546
|
+
exit 1
|
|
547
|
+
fi
|
|
548
|
+
fi
|
|
549
|
+
else
|
|
550
|
+
print_info "Creating virtual environment at $VENV_DIR..."
|
|
551
|
+
if create_venv; then
|
|
552
|
+
print_success "Virtual environment created"
|
|
553
|
+
else
|
|
554
|
+
print_error "Failed to create virtual environment"
|
|
555
|
+
exit 1
|
|
556
|
+
fi
|
|
557
|
+
fi
|
|
558
|
+
|
|
559
|
+
# Activate and install packages
|
|
560
|
+
print_info "Activating virtual environment..."
|
|
561
|
+
source "$VENV_DIR/bin/activate"
|
|
562
|
+
|
|
563
|
+
# Create log directory
|
|
564
|
+
local LOG_DIR="$VENV_DIR/logs"
|
|
565
|
+
mkdir -p "$LOG_DIR"
|
|
566
|
+
|
|
567
|
+
# Upgrade pip with logging (use --prefer-binary)
|
|
568
|
+
print_info "Upgrading pip..."
|
|
569
|
+
if pip install --upgrade pip --prefer-binary 2>&1 | tee "$LOG_DIR/pip-upgrade.log" | tail -n 3; then
|
|
570
|
+
print_success "pip upgraded successfully"
|
|
571
|
+
else
|
|
572
|
+
print_warning "pip upgrade failed (continuing anyway)"
|
|
573
|
+
print_info "See log: $LOG_DIR/pip-upgrade.log"
|
|
574
|
+
fi
|
|
575
|
+
|
|
576
|
+
# Install dependencies from all skills' requirements.txt files
|
|
577
|
+
print_info "Installing Python dependencies from all skills..."
|
|
578
|
+
|
|
579
|
+
local installed_count=0
|
|
580
|
+
for skill_dir in "$SCRIPT_DIR"/*; do
|
|
581
|
+
if [ -d "$skill_dir" ]; then
|
|
582
|
+
skill_name=$(basename "$skill_dir")
|
|
583
|
+
|
|
584
|
+
# Skip .venv and document-skills
|
|
585
|
+
if [ "$skill_name" == ".venv" ] || [ "$skill_name" == "document-skills" ]; then
|
|
586
|
+
continue
|
|
587
|
+
fi
|
|
588
|
+
|
|
589
|
+
# Install main requirements.txt with wheel-first approach
|
|
590
|
+
if [ -f "$skill_dir/scripts/requirements.txt" ]; then
|
|
591
|
+
local SKILL_LOG="$LOG_DIR/install-${skill_name}.log"
|
|
592
|
+
|
|
593
|
+
print_info "Installing $skill_name dependencies..."
|
|
594
|
+
|
|
595
|
+
# Read requirements and install one-by-one for granular tracking
|
|
596
|
+
local pkg_success=0
|
|
597
|
+
local pkg_fail=0
|
|
598
|
+
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
599
|
+
# Skip comments and empty lines
|
|
600
|
+
[[ "$line" =~ ^#.*$ ]] && continue
|
|
601
|
+
[[ -z "${line// }" ]] && continue
|
|
602
|
+
|
|
603
|
+
# Strip inline comments (e.g., "package>=1.0 # comment" -> "package>=1.0")
|
|
604
|
+
line="${line%%#*}"
|
|
605
|
+
line="${line%"${line##*[![:space:]]}"}" # trim trailing whitespace
|
|
606
|
+
[[ -z "$line" ]] && continue
|
|
607
|
+
|
|
608
|
+
if try_pip_install "$line" "$SKILL_LOG"; then
|
|
609
|
+
pkg_success=$((pkg_success + 1))
|
|
610
|
+
else
|
|
611
|
+
pkg_fail=$((pkg_fail + 1))
|
|
612
|
+
track_failure "optional" "$skill_name:$line" "Package install failed"
|
|
613
|
+
fi
|
|
614
|
+
done < "$skill_dir/scripts/requirements.txt"
|
|
615
|
+
|
|
616
|
+
if [[ $pkg_fail -eq 0 ]]; then
|
|
617
|
+
print_success "$skill_name: all $pkg_success packages installed"
|
|
618
|
+
track_success "optional" "$skill_name"
|
|
619
|
+
successful_skills+=("$skill_name")
|
|
620
|
+
installed_count=$((installed_count + 1))
|
|
621
|
+
else
|
|
622
|
+
print_warning "$skill_name: $pkg_success installed, $pkg_fail failed"
|
|
623
|
+
failed_skills+=("$skill_name")
|
|
624
|
+
fi
|
|
625
|
+
fi
|
|
626
|
+
|
|
627
|
+
# Install test requirements.txt
|
|
628
|
+
if [ -f "$skill_dir/scripts/tests/requirements.txt" ]; then
|
|
629
|
+
local SKILL_TEST_LOG="$LOG_DIR/install-${skill_name}-tests.log"
|
|
630
|
+
|
|
631
|
+
print_info "Installing $skill_name test dependencies..."
|
|
632
|
+
|
|
633
|
+
if pip install -r "$skill_dir/scripts/tests/requirements.txt" --prefer-binary 2>&1 | tee "$SKILL_TEST_LOG"; then
|
|
634
|
+
print_success "$skill_name test dependencies installed successfully"
|
|
635
|
+
else
|
|
636
|
+
print_warning "$skill_name test dependencies failed to install"
|
|
637
|
+
# Don't fail installation if test deps fail (less critical)
|
|
638
|
+
fi
|
|
639
|
+
fi
|
|
640
|
+
fi
|
|
641
|
+
done
|
|
642
|
+
|
|
643
|
+
# Install %USERPROFILE%/.claude/scripts requirements (contains pyyaml for generate_catalogs.py)
|
|
644
|
+
local SCRIPTS_REQ="$SCRIPT_DIR/../scripts/requirements.txt"
|
|
645
|
+
if [ -f "$SCRIPTS_REQ" ]; then
|
|
646
|
+
local SCRIPTS_LOG="$LOG_DIR/install-scripts.log"
|
|
647
|
+
print_info "Installing %USERPROFILE%/.claude/scripts dependencies..."
|
|
648
|
+
|
|
649
|
+
local pkg_success=0
|
|
650
|
+
local pkg_fail=0
|
|
651
|
+
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
652
|
+
[[ "$line" =~ ^#.*$ ]] && continue
|
|
653
|
+
[[ -z "${line// }" ]] && continue
|
|
654
|
+
line="${line%%#*}"
|
|
655
|
+
line="${line%"${line##*[![:space:]]}"}"
|
|
656
|
+
[[ -z "$line" ]] && continue
|
|
657
|
+
|
|
658
|
+
if try_pip_install "$line" "$SCRIPTS_LOG"; then
|
|
659
|
+
pkg_success=$((pkg_success + 1))
|
|
660
|
+
else
|
|
661
|
+
pkg_fail=$((pkg_fail + 1))
|
|
662
|
+
track_failure "optional" "scripts:$line" "Package install failed"
|
|
663
|
+
fi
|
|
664
|
+
done < "$SCRIPTS_REQ"
|
|
665
|
+
|
|
666
|
+
if [[ $pkg_fail -eq 0 ]]; then
|
|
667
|
+
print_success "%USERPROFILE%/.claude/scripts: all $pkg_success packages installed"
|
|
668
|
+
track_success "optional" "scripts"
|
|
669
|
+
else
|
|
670
|
+
print_warning "%USERPROFILE%/.claude/scripts: $pkg_success installed, $pkg_fail failed"
|
|
671
|
+
fi
|
|
672
|
+
fi
|
|
673
|
+
|
|
674
|
+
# Print installation summary (brief - final report comes later)
|
|
675
|
+
print_header "Python Dependencies Installation Summary"
|
|
676
|
+
|
|
677
|
+
if [ ${#successful_skills[@]} -gt 0 ]; then
|
|
678
|
+
print_success "Successfully installed ${#successful_skills[@]} skill(s)"
|
|
679
|
+
fi
|
|
680
|
+
|
|
681
|
+
if [ ${#failed_skills[@]} -gt 0 ]; then
|
|
682
|
+
print_warning "${#failed_skills[@]} skill(s) had package failures (see final report)"
|
|
683
|
+
# Don't exit 1 - track failures instead and continue
|
|
684
|
+
elif [ ${#successful_skills[@]} -eq 0 ]; then
|
|
685
|
+
print_warning "No skill requirements.txt files found"
|
|
686
|
+
else
|
|
687
|
+
print_success "All Python dependencies installed successfully"
|
|
688
|
+
fi
|
|
689
|
+
|
|
690
|
+
deactivate
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
# Verify installations
|
|
694
|
+
verify_installations() {
|
|
695
|
+
print_header "Verifying Installations"
|
|
696
|
+
|
|
697
|
+
# FFmpeg
|
|
698
|
+
if command_exists ffmpeg; then
|
|
699
|
+
print_success "FFmpeg is available"
|
|
700
|
+
else
|
|
701
|
+
print_warning "FFmpeg is not available"
|
|
702
|
+
fi
|
|
703
|
+
|
|
704
|
+
# ImageMagick (check both magick and convert - older versions use convert)
|
|
705
|
+
if command_exists magick || command_exists convert; then
|
|
706
|
+
print_success "ImageMagick is available"
|
|
707
|
+
else
|
|
708
|
+
print_warning "ImageMagick is not available"
|
|
709
|
+
fi
|
|
710
|
+
|
|
711
|
+
# Node.js & npm
|
|
712
|
+
if command_exists node; then
|
|
713
|
+
print_success "Node.js is available"
|
|
714
|
+
else
|
|
715
|
+
print_warning "Node.js is not available"
|
|
716
|
+
fi
|
|
717
|
+
|
|
718
|
+
if command_exists npm; then
|
|
719
|
+
print_success "npm is available"
|
|
720
|
+
else
|
|
721
|
+
print_warning "npm is not available"
|
|
722
|
+
fi
|
|
723
|
+
|
|
724
|
+
declare -a npm_packages=(
|
|
725
|
+
"rmbg"
|
|
726
|
+
"pnpm"
|
|
727
|
+
"wrangler"
|
|
728
|
+
"repomix"
|
|
729
|
+
)
|
|
730
|
+
|
|
731
|
+
for package in "${npm_packages[@]}"; do
|
|
732
|
+
if command_exists "$package"; then
|
|
733
|
+
print_success "$package CLI is available"
|
|
734
|
+
else
|
|
735
|
+
print_warning "$package CLI is not available"
|
|
736
|
+
fi
|
|
737
|
+
done
|
|
738
|
+
|
|
739
|
+
# Check Python packages
|
|
740
|
+
if [ -d "$VENV_DIR" ]; then
|
|
741
|
+
source "$VENV_DIR/bin/activate"
|
|
742
|
+
if python -c "import google.genai" 2>/dev/null; then
|
|
743
|
+
print_success "google-genai Python package is available"
|
|
744
|
+
else
|
|
745
|
+
print_warning "google-genai Python package is not available"
|
|
746
|
+
fi
|
|
747
|
+
deactivate
|
|
748
|
+
fi
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
# ============================================================================
|
|
752
|
+
# Final Report Functions
|
|
753
|
+
# ============================================================================
|
|
754
|
+
|
|
755
|
+
generate_remediation_commands() {
|
|
756
|
+
local has_sudo_skipped=false
|
|
757
|
+
local has_python_failed=false
|
|
758
|
+
|
|
759
|
+
# Check if we have sudo-skipped packages
|
|
760
|
+
if [[ ${#SKIPPED_SUDO[@]} -gt 0 ]]; then
|
|
761
|
+
has_sudo_skipped=true
|
|
762
|
+
fi
|
|
763
|
+
|
|
764
|
+
# Check if we have Python package failures
|
|
765
|
+
if [[ ${#FAILED_OPTIONAL[@]} -gt 0 ]]; then
|
|
766
|
+
has_python_failed=true
|
|
767
|
+
fi
|
|
768
|
+
|
|
769
|
+
if [[ "$has_sudo_skipped" == "false" ]] && [[ "$has_python_failed" == "false" ]]; then
|
|
770
|
+
return 0
|
|
771
|
+
fi
|
|
772
|
+
|
|
773
|
+
echo ""
|
|
774
|
+
echo -e "${BLUE}---------------------------------------------------${NC}"
|
|
775
|
+
echo -e "${BLUE}Manual Installation Commands:${NC}"
|
|
776
|
+
echo -e "${BLUE}---------------------------------------------------${NC}"
|
|
777
|
+
echo ""
|
|
778
|
+
|
|
779
|
+
if [[ "$has_sudo_skipped" == "true" ]]; then
|
|
780
|
+
echo "# System packages (requires sudo):"
|
|
781
|
+
echo "sudo apt-get update"
|
|
782
|
+
for item in "${SKIPPED_SUDO[@]}"; do
|
|
783
|
+
local pkg="${item%%:*}"
|
|
784
|
+
case "$pkg" in
|
|
785
|
+
FFmpeg) echo "sudo apt-get install -y ffmpeg" ;;
|
|
786
|
+
ImageMagick) echo "sudo apt-get install -y imagemagick" ;;
|
|
787
|
+
*) echo "# $pkg: see documentation" ;;
|
|
788
|
+
esac
|
|
789
|
+
done
|
|
790
|
+
echo ""
|
|
791
|
+
fi
|
|
792
|
+
|
|
793
|
+
if [[ "$has_python_failed" == "true" ]]; then
|
|
794
|
+
echo "# Python packages (may require build tools):"
|
|
795
|
+
if [[ "$OS" == "linux" ]]; then
|
|
796
|
+
echo "sudo apt-get install -y gcc python3-dev libjpeg-dev zlib1g-dev"
|
|
797
|
+
elif [[ "$OS" == "macos" ]]; then
|
|
798
|
+
echo "xcode-select --install"
|
|
799
|
+
echo "brew install jpeg libpng"
|
|
800
|
+
fi
|
|
801
|
+
echo "source $VENV_DIR/bin/activate"
|
|
802
|
+
|
|
803
|
+
for item in "${FAILED_OPTIONAL[@]}"; do
|
|
804
|
+
local pkg="${item%%:*}"
|
|
805
|
+
# Extract package name from skill:package format
|
|
806
|
+
if [[ "$pkg" == *":"* ]]; then
|
|
807
|
+
pkg="${pkg#*:}"
|
|
808
|
+
fi
|
|
809
|
+
echo "pip install $pkg"
|
|
810
|
+
done
|
|
811
|
+
echo ""
|
|
812
|
+
fi
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
print_final_report() {
|
|
816
|
+
echo ""
|
|
817
|
+
echo -e "${BLUE}===================================================${NC}"
|
|
818
|
+
echo -e "${BLUE} Installation Report${NC}"
|
|
819
|
+
echo -e "${BLUE}===================================================${NC}"
|
|
820
|
+
echo ""
|
|
821
|
+
|
|
822
|
+
# Installed section
|
|
823
|
+
local installed_count=$((${#INSTALLED_CRITICAL[@]} + ${#INSTALLED_OPTIONAL[@]}))
|
|
824
|
+
if [[ $installed_count -gt 0 ]]; then
|
|
825
|
+
echo -e "${GREEN}Installed ($installed_count):${NC}"
|
|
826
|
+
for item in "${INSTALLED_CRITICAL[@]}"; do
|
|
827
|
+
echo -e " ${GREEN}✓${NC} $item"
|
|
828
|
+
done
|
|
829
|
+
for item in "${INSTALLED_OPTIONAL[@]}"; do
|
|
830
|
+
echo -e " ${GREEN}✓${NC} $item"
|
|
831
|
+
done
|
|
832
|
+
echo ""
|
|
833
|
+
fi
|
|
834
|
+
|
|
835
|
+
# Skipped section
|
|
836
|
+
if [[ ${#SKIPPED_SUDO[@]} -gt 0 ]]; then
|
|
837
|
+
echo -e "${YELLOW}Skipped (${#SKIPPED_SUDO[@]}):${NC}"
|
|
838
|
+
for item in "${SKIPPED_SUDO[@]}"; do
|
|
839
|
+
local name="${item%%:*}"
|
|
840
|
+
local reason="${item#*:}"
|
|
841
|
+
echo -e " ${YELLOW}~${NC} $name (${reason# })"
|
|
842
|
+
done
|
|
843
|
+
echo ""
|
|
844
|
+
fi
|
|
845
|
+
|
|
846
|
+
# Degraded/Failed section
|
|
847
|
+
if [[ ${#FAILED_OPTIONAL[@]} -gt 0 ]]; then
|
|
848
|
+
echo -e "${RED}Degraded (${#FAILED_OPTIONAL[@]}):${NC}"
|
|
849
|
+
for item in "${FAILED_OPTIONAL[@]}"; do
|
|
850
|
+
local name="${item%%:*}"
|
|
851
|
+
local reason="${item#*:}"
|
|
852
|
+
echo -e " ${RED}!${NC} $name (${reason# })"
|
|
853
|
+
done
|
|
854
|
+
echo ""
|
|
855
|
+
fi
|
|
856
|
+
|
|
857
|
+
# Remediation commands
|
|
858
|
+
generate_remediation_commands
|
|
859
|
+
|
|
860
|
+
# Exit status line
|
|
861
|
+
echo -e "${BLUE}===================================================${NC}"
|
|
862
|
+
case $FINAL_EXIT_CODE in
|
|
863
|
+
0) echo -e " ${GREEN}Exit: 0 (success - all dependencies installed)${NC}" ;;
|
|
864
|
+
1) echo -e " ${RED}Exit: 1 (failed - critical dependencies missing)${NC}" ;;
|
|
865
|
+
2) echo -e " ${YELLOW}Exit: 2 (partial - some optional deps failed)${NC}" ;;
|
|
866
|
+
esac
|
|
867
|
+
echo -e "${BLUE}===================================================${NC}"
|
|
868
|
+
echo ""
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
# Escape string for JSON (handle all special chars)
|
|
872
|
+
json_escape() {
|
|
873
|
+
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g' | tr '\n' ' ' | tr '\r' ' ' | tr '\t' ' '
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
# Write structured error summary for CLI to parse
|
|
877
|
+
write_error_summary() {
|
|
878
|
+
# Only write if there are failures
|
|
879
|
+
if [[ $FINAL_EXIT_CODE -eq 0 ]]; then
|
|
880
|
+
return 0
|
|
881
|
+
fi
|
|
882
|
+
|
|
883
|
+
# Write to a file that CLI can read
|
|
884
|
+
local summary_file="$SCRIPT_DIR/.install-error-summary.json"
|
|
885
|
+
|
|
886
|
+
# Build JSON arrays carefully for bash compatibility
|
|
887
|
+
local critical_json="[]"
|
|
888
|
+
local optional_json="[]"
|
|
889
|
+
local skipped_json="[]"
|
|
890
|
+
|
|
891
|
+
if [[ ${#FAILED_OPTIONAL[@]} -gt 0 ]]; then
|
|
892
|
+
optional_json="["
|
|
893
|
+
local first=true
|
|
894
|
+
for item in "${FAILED_OPTIONAL[@]}"; do
|
|
895
|
+
if [[ "$first" == "true" ]]; then
|
|
896
|
+
first=false
|
|
897
|
+
else
|
|
898
|
+
optional_json+=","
|
|
899
|
+
fi
|
|
900
|
+
optional_json+="\"$(json_escape "$item")\""
|
|
901
|
+
done
|
|
902
|
+
optional_json+="]"
|
|
903
|
+
fi
|
|
904
|
+
|
|
905
|
+
if [[ ${#SKIPPED_SUDO[@]} -gt 0 ]]; then
|
|
906
|
+
skipped_json="["
|
|
907
|
+
local first=true
|
|
908
|
+
for item in "${SKIPPED_SUDO[@]}"; do
|
|
909
|
+
if [[ "$first" == "true" ]]; then
|
|
910
|
+
first=false
|
|
911
|
+
else
|
|
912
|
+
skipped_json+=","
|
|
913
|
+
fi
|
|
914
|
+
skipped_json+="\"$(json_escape "$item")\""
|
|
915
|
+
done
|
|
916
|
+
skipped_json+="]"
|
|
917
|
+
fi
|
|
918
|
+
|
|
919
|
+
cat > "$summary_file" << EOF
|
|
920
|
+
{
|
|
921
|
+
"exit_code": $FINAL_EXIT_CODE,
|
|
922
|
+
"timestamp": "$(date -Iseconds 2>/dev/null || date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
923
|
+
"critical_failures": $critical_json,
|
|
924
|
+
"optional_failures": $optional_json,
|
|
925
|
+
"skipped": $skipped_json,
|
|
926
|
+
"remediation": {
|
|
927
|
+
"sudo_packages": "sudo apt-get install -y ffmpeg imagemagick",
|
|
928
|
+
"build_tools": "sudo apt-get install -y gcc python3-dev libjpeg-dev zlib1g-dev",
|
|
929
|
+
"pip_retry": "source $VENV_DIR/bin/activate && pip install <package>"
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
EOF
|
|
933
|
+
|
|
934
|
+
print_info "Error summary written to: $summary_file"
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
# Print usage instructions (now just brief tips)
|
|
938
|
+
print_usage() {
|
|
939
|
+
echo -e "${GREEN}To use the Python virtual environment:${NC}"
|
|
940
|
+
echo -e " source %USERPROFILE%/.claude/skills/.venv/bin/activate"
|
|
941
|
+
echo ""
|
|
942
|
+
echo -e "${BLUE}For more information, see:${NC}"
|
|
943
|
+
echo -e " %USERPROFILE%/.claude/skills/INSTALLATION.md"
|
|
944
|
+
echo ""
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
# Main installation flow
|
|
948
|
+
main() {
|
|
949
|
+
echo "" # Just add spacing, don't clear terminal
|
|
950
|
+
print_header "Claude Code Skills Installation"
|
|
951
|
+
print_info "OS: $OS"
|
|
952
|
+
print_info "Script directory: $SCRIPT_DIR"
|
|
953
|
+
if [[ "$WITH_SUDO" == "true" ]]; then
|
|
954
|
+
print_info "Mode: with sudo (--with-sudo)"
|
|
955
|
+
else
|
|
956
|
+
print_info "Mode: without sudo (system packages will be skipped)"
|
|
957
|
+
fi
|
|
958
|
+
if [[ "$RESUME_MODE" == "true" ]]; then
|
|
959
|
+
print_info "Mode: resuming previous installation"
|
|
960
|
+
fi
|
|
961
|
+
echo ""
|
|
962
|
+
|
|
963
|
+
if [[ "$OS" == "unknown" ]]; then
|
|
964
|
+
print_error "Unsupported operating system"
|
|
965
|
+
exit 1
|
|
966
|
+
fi
|
|
967
|
+
|
|
968
|
+
# Confirm installation (skip if --yes flag or NON_INTERACTIVE env is set)
|
|
969
|
+
if [[ "$SKIP_CONFIRM" == "false" ]]; then
|
|
970
|
+
read -p "This will install system packages and Node.js dependencies. Continue? (y/N) " -n 1 -r
|
|
971
|
+
echo
|
|
972
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
973
|
+
print_warning "Installation cancelled"
|
|
974
|
+
exit 0
|
|
975
|
+
fi
|
|
976
|
+
else
|
|
977
|
+
print_info "Auto-confirming installation (--yes flag or NON_INTERACTIVE mode)"
|
|
978
|
+
fi
|
|
979
|
+
|
|
980
|
+
# Initialize state tracking
|
|
981
|
+
init_state
|
|
982
|
+
|
|
983
|
+
# Phase 1: System deps
|
|
984
|
+
if phase_done "system_deps"; then
|
|
985
|
+
print_success "System deps: already processed (resume)"
|
|
986
|
+
else
|
|
987
|
+
update_phase "system_deps" "running"
|
|
988
|
+
check_package_manager
|
|
989
|
+
install_system_deps
|
|
990
|
+
update_phase "system_deps" "done"
|
|
991
|
+
fi
|
|
992
|
+
|
|
993
|
+
# Phase 2: Node deps
|
|
994
|
+
if phase_done "node_deps"; then
|
|
995
|
+
print_success "Node deps: already installed (resume)"
|
|
996
|
+
else
|
|
997
|
+
update_phase "node_deps" "running"
|
|
998
|
+
install_node_deps
|
|
999
|
+
update_phase "node_deps" "done"
|
|
1000
|
+
fi
|
|
1001
|
+
|
|
1002
|
+
# Phase 3: Python env
|
|
1003
|
+
if phase_done "python_env"; then
|
|
1004
|
+
print_success "Python env: already set up (resume)"
|
|
1005
|
+
else
|
|
1006
|
+
update_phase "python_env" "running"
|
|
1007
|
+
setup_python_env
|
|
1008
|
+
update_phase "python_env" "done"
|
|
1009
|
+
fi
|
|
1010
|
+
|
|
1011
|
+
# Phase 4: Verify
|
|
1012
|
+
update_phase "verify" "running"
|
|
1013
|
+
verify_installations
|
|
1014
|
+
update_phase "verify" "done"
|
|
1015
|
+
|
|
1016
|
+
# Print final report with all tracking info
|
|
1017
|
+
print_final_report
|
|
1018
|
+
print_usage
|
|
1019
|
+
|
|
1020
|
+
# Write error summary for CLI to parse
|
|
1021
|
+
write_error_summary
|
|
1022
|
+
|
|
1023
|
+
# Clean state on complete success
|
|
1024
|
+
if [[ "$FINAL_EXIT_CODE" -eq 0 ]]; then
|
|
1025
|
+
clean_state
|
|
1026
|
+
fi
|
|
1027
|
+
|
|
1028
|
+
exit $FINAL_EXIT_CODE
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
# Run main function
|
|
1032
|
+
main
|