codewave-openclaw-installer 2.1.12 → 2.2.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/bin/install-lib.mjs +11 -0
- package/bin/install.mjs +59 -1
- package/package.json +12 -1
- package/skills/acceptance-doc-entry/SKILL.md +54 -1
- package/skills/ppt-master/SKILL.md +17 -390
- package/skills/ppt-master/projects/.gitkeep +0 -0
- package/skills/ppt-master/references/executor-base.md +4 -3
- package/skills/ppt-master/references/image-generator.md +6 -93
- package/skills/ppt-master/references/strategist.md +5 -8
- package/skills/ppt-master/scripts/README.md +1 -1
- package/skills/ppt-master/scripts/finalize_svg.py +0 -14
- package/skills/ppt-master/scripts/svg_quality_checker.py +8 -169
- package/skills/ppt-master/scripts/svg_to_pptx/pptx_builder.py +1 -7
- package/skills/ppt-master/scripts/svg_to_pptx/pptx_cli.py +0 -14
- package/skills/risk-alert/SKILL.md +110 -0
- package/skills/risk-alert/config.example.json +21 -0
- package/skills/risk-alert/scheduler.sh +74 -0
- package/skills/risk-alert/scripts/analyze-risk.js +414 -0
- package/skills/risk-alert/scripts/config-manager.js +241 -0
- package/skills/risk-alert/scripts/push-beautiful.js +225 -0
- package/skills/risk-alert/scripts/risk-alert.js +136 -0
- package/skills/risk-alert/scripts/run-full.js +60 -0
- package/skills/risk-alert/trigger-risk-alert.sh +35 -0
- package/skills/ppt-master/.env.example +0 -35
- package/skills/ppt-master/README.md +0 -90
- package/skills/ppt-master/audit_report_model_perf.md +0 -213
- package/skills/ppt-master/audit_report_portability.md +0 -90
- package/skills/ppt-master/audit_report_robustness.md +0 -192
- package/skills/ppt-master/audit_report_workflow.md +0 -233
- package/skills/ppt-master/fix_report_bid.md +0 -51
- package/skills/ppt-master/fix_report_scripts.md +0 -41
- package/skills/ppt-master/references/bid-content-example-netease.md +0 -815
- package/skills/ppt-master/references/bid-content-template.md +0 -390
- package/skills/ppt-master/references/bid-example-netease.md +0 -339
- package/skills/ppt-master/references/bid-presentation.md +0 -384
- package/skills/ppt-master/references/bid-svgs/03_toc.svg +0 -38
- package/skills/ppt-master/references/bid-svgs/04_chapter_company.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/05_company_overview.svg +0 -28
- package/skills/ppt-master/references/bid-svgs/06_vision_business.svg +0 -45
- package/skills/ppt-master/references/bid-svgs/07_product_system.svg +0 -52
- package/skills/ppt-master/references/bid-svgs/08_codewave_timeline.svg +0 -29
- package/skills/ppt-master/references/bid-svgs/09_certifications.svg +0 -33
- package/skills/ppt-master/references/bid-svgs/10_client_logos.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/11_brand_mission.svg +0 -14
- package/skills/ppt-master/references/bid-svgs/12_chapter_demand.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/16_chapter_advantages.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/18_platform_arch.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/19_function_matrix.svg +0 -35
- package/skills/ppt-master/references/bid-svgs/20_dev_arch.svg +0 -29
- package/skills/ppt-master/references/bid-svgs/21_source_code.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/22_ai_dev.svg +0 -27
- package/skills/ppt-master/references/bid-svgs/23_asset_market.svg +0 -33
- package/skills/ppt-master/references/bid-svgs/24_multi_org.svg +0 -28
- package/skills/ppt-master/references/bid-svgs/25_i18n.svg +0 -22
- package/skills/ppt-master/references/bid-svgs/26_multi_tenant.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/27_integration.svg +0 -27
- package/skills/ppt-master/references/bid-svgs/28_permission.svg +0 -31
- package/skills/ppt-master/references/bid-svgs/29_security.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/30_ai_capabilities.svg +0 -21
- package/skills/ppt-master/references/bid-svgs/31_product_combo.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/32_digital_transform.svg +0 -28
- package/skills/ppt-master/references/bid-svgs/33_chapter_cases.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/34_cummins_case.svg +0 -23
- package/skills/ppt-master/references/bid-svgs/35_cpq_cost.svg +0 -22
- package/skills/ppt-master/references/bid-svgs/36_tech_platform.svg +0 -18
- package/skills/ppt-master/references/bid-svgs/37_platform_value.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/38_operation_plan.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/39_zpmc_case.svg +0 -21
- package/skills/ppt-master/references/bid-svgs/40_zpmc_apps.svg +0 -23
- package/skills/ppt-master/references/bid-svgs/41_chapter_service.svg +0 -7
- package/skills/ppt-master/references/bid-svgs/42_tech_support.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/43_knowledge_transfer.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/44_operation_promotion.svg +0 -20
- package/skills/ppt-master/references/bid-svgs/45_custom_dev_guide.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/46_sla_guarantee.svg +0 -18
- package/skills/ppt-master/references/bid-svgs/47_strategic_cooperation.svg +0 -25
- package/skills/ppt-master/references/bid-svgs/48_ecosystem.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/49_chapter_delivery.svg +0 -23
- package/skills/ppt-master/references/bid-svgs/53_pm_intro.svg +0 -24
- package/skills/ppt-master/references/bid-svgs/54_after_sales.svg +0 -27
- package/skills/ppt-master/references/bid-svgs/55_ending.svg +0 -8
- package/skills/ppt-master/references/company_intro.md +0 -93
- package/skills/ppt-master/references/company_intro_images/slide1_img00.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img01.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img02.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img03.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img04.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img05.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img06.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img07.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img08.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img09.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img10.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img11.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img12.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img13.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img14.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img15.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img16.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img17.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img18.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img19.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img20.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img21.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img22.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img23.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img24.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img25.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img26.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img27.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img28.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide1_img29.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide2_img30.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide2_img31.jpg +0 -0
- package/skills/ppt-master/references/company_intro_images/slide3_img32.png +0 -0
- package/skills/ppt-master/references/company_intro_images/slide3_img33.png +0 -0
- package/skills/ppt-master/references/drawio-integration.md +0 -144
- package/skills/ppt-master/requirements.txt +0 -19
- package/skills/ppt-master/resources/backgrounds/chapter_bg.png +0 -0
- package/skills/ppt-master/resources/backgrounds/company_bg.png +0 -0
- package/skills/ppt-master/resources/backgrounds/cover_bg.png +0 -0
- package/skills/ppt-master/resources/backgrounds/index.json +0 -40
- package/skills/ppt-master/resources/backgrounds/tech_bg.png +0 -0
- package/skills/ppt-master/scripts/__pycache__/config.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/__pycache__/error_helper.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/__pycache__/pptx_animations.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/__pycache__/project_utils.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/arch_diagram.py +0 -370
- package/skills/ppt-master/scripts/bid_init.py +0 -79
- package/skills/ppt-master/scripts/drawio_gen.py +0 -366
- package/skills/ppt-master/scripts/drawio_to_svg.py +0 -458
- package/skills/ppt-master/scripts/image_backends/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/image_backends/__pycache__/backend_aigw_gemini.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/image_backends/__pycache__/backend_common.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/crop_images.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_icons.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_images.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/fix_image_aspect.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/flatten_tspan.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_finalize/__pycache__/svg_rect_to_path.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_page_gen.py +0 -871
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_context.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_converter.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_elements.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_paths.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_styles.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_utils.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_builder.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_cli.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_dimensions.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_discovery.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_media.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_notes.cpython-314.pyc +0 -0
- package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_slide_xml.cpython-314.pyc +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//316/243/342/225/225/302/241/317/203/302/242/342/225/234/302/265/342/226/221/342/224/244/317/203e/314/200i/314/201logo.png" → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204//344/270/255/345/233/275/346/260/264/345/212/241logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//317/203i/314/200A/314/210/316/243/342/225/225/302/243/316/230O/314/210o/314/201logo.png" → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204//345/215/216/344/270/234/351/231/242logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//302/265/342/226/221/342/224/244/317/204o/314/210/342/225/241/316/243/342/225/225e/314/210/317/203/342/226/222C/314/247logo.png" → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204//346/260/264/347/224/265/344/270/211/345/261/200logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221logo.png" → 344/270/255/345/233/275/347/224/265/345/273/272_/345/270/270/350/247/204//347/224/265/345/273/272logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//316/243/342/225/225/302/241/317/203/302/242/342/225/234/302/265/342/226/221/342/224/244/317/203e/314/200i/314/201logo.png" → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243//344/270/255/345/233/275/346/260/264/345/212/241logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//317/203i/314/200A/314/210/316/243/342/225/225/302/243/316/230O/314/210o/314/201logo.png" → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243//345/215/216/344/270/234/351/231/242logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//302/265/342/226/221/342/224/244/317/204o/314/210/342/225/241/316/243/342/225/225e/314/210/317/203/342/226/222C/314/247logo.png" → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243//346/260/264/347/224/265/344/270/211/345/261/200logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/317/203/302/242/342/225/234/317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//317/204o/314/210/342/225/241/317/203/342/225/227/342/225/221logo.png" → 344/270/255/345/233/275/347/224/265/345/273/272_/347/216/260/344/273/243//347/224/265/345/273/272logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201//317/203A/314/212/342/224/202/316/243/342/225/225e/314/200/316/246/302/272/303/206 logo.png" → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241//345/217/263/344/270/212/350/247/222 logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203o/314/200a/314/212/317/203e/314/200i/314/201//317/203n/314/203/302/272/317/203/342/202/247i/314/210 logo.png" → 344/270/255/346/261/275/347/240/224_/345/225/206/345/212/241//345/244/247/345/236/213 logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210 → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//317/203A/314/212/342/224/202/316/243/342/225/225e/314/200/316/246/302/272/303/206 logo.png" → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204//345/217/263/344/270/212/350/247/222 logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/203/342/225/225/342/225/225/316/246/302/272a/314/210//317/203n/314/203/302/272/317/203/342/202/247i/314/210 logo.png" → 344/270/255/346/261/275/347/240/224_/345/270/270/350/247/204//345/244/247/345/236/213 logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201 → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//317/203A/314/212/342/224/202/316/243/342/225/225e/314/200/316/246/302/272/303/206 logo.png" → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243//345/217/263/344/270/212/350/247/222 logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{316/243/342/225/225/302/241/302/265/342/226/222/342/225/234/317/204a/314/201o/314/210_/317/204A/314/210/342/226/221/316/243/342/225/227u/314/201//317/203n/314/203/302/272/317/203/342/202/247i/314/210 logo.png" → 344/270/255/346/261/275/347/240/224_/347/216/260/344/273/243//345/244/247/345/236/213 logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202 → 346/213/233/345/225/206/351/223/266/350/241/214}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202 → 346/213/233/345/225/206/351/223/266/350/241/214}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202 → 346/213/233/345/225/206/351/223/266/350/241/214}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202 → 346/213/233/345/225/206/351/223/266/350/241/214}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202 → 346/213/233/345/225/206/351/223/266/350/241/214}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202 → 346/213/233/345/225/206/351/223/266/350/241/214}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts//{302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202//302/265i/314/210/302/242/317/203o/314/200a/314/212/316/230o/314/202/342/225/242/316/246i/314/201i/314/202/317/203a/314/200/302/274/317/203A/314/212/342/225/225/316/230c/314/247/303/246/316/246/342/202/247i/314/200.png" → 346/213/233/345/225/206/351/223/266/350/241/214//346/213/233/345/225/206/351/223/266/350/241/214/345/205/254/345/217/270/351/207/221/350/236/215.png"} +0 -0
- /package/skills/ppt-master/templates/layouts//{317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/01_cover.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/02_chapter.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/02_toc.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/03_content.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/04_ending.svg" +0 -0
- /package/skills/ppt-master/templates/layouts//{317/204/302/272/303/246/302/265e/314/200C/314/247/316/246o/314/202/302/245/317/203o/314/200a/314/212/317/203e/314/200i/314/201 → 347/247/221/346/212/200/350/223/235/345/225/206/345/212/241}/design_spec.md" +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/01_cover.svg → /351/207/215/345/272/206/345/244/247/345/255/246/01_cover.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/02_chapter.svg → /351/207/215/345/272/206/345/244/247/345/255/246/02_chapter.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/02_toc.svg → /351/207/215/345/272/206/345/244/247/345/255/246/02_toc.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/03_content.svg → /351/207/215/345/272/206/345/244/247/345/255/246/03_content.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/04_ending.svg → /351/207/215/345/272/206/345/244/247/345/255/246/04_ending.svg"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business/design_spec.md → /351/207/215/345/272/206/345/244/247/345/255/246/design_spec.md"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business//316/230c/314/247i/314/200/317/203/342/225/221a/314/212/317/203n/314/203/302/272/317/203/302/241/302/252logo.png" → /351/207/215/345/272/206/345/244/247/345/255/246//351/207/215/345/272/206/345/244/247/345/255/246logo.png"} +0 -0
- /package/skills/ppt-master/templates/layouts/{Technology Blue Business//316/230c/314/247i/314/200/317/203/342/225/221a/314/212/317/203n/314/203/302/272/317/203/302/241/302/252logo2.png" → /351/207/215/345/272/206/345/244/247/345/255/246//351/207/215/345/272/206/345/244/247/345/255/246logo2.png"} +0 -0
|
@@ -114,38 +114,12 @@ Full directive: "color palette: deep navy blue (#1E3A5F), light gray (#F8F9FA),
|
|
|
114
114
|
|
|
115
115
|
### Type Determination Flow
|
|
116
116
|
|
|
117
|
-
0. **Architecture / topology / system overview → 🌟 Architecture Diagram (3.0) — HIGHEST PRIORITY, all modes**
|
|
118
117
|
1. Full-page / large-area backdrop → **Background** (3.1)
|
|
119
118
|
2. Real scenes / people / products → **Photography** (3.2)
|
|
120
119
|
3. Flat / illustration / cartoon style → **Illustration** (3.3)
|
|
121
120
|
4. Process / architecture / relationships → **Diagram** (3.4)
|
|
122
121
|
5. Partial decoration / texture → **Decorative Pattern** (3.5)
|
|
123
122
|
|
|
124
|
-
### 3.0 Architecture Diagram (🌟 Core Feature — All Modes)
|
|
125
|
-
|
|
126
|
-
**Identifying characteristics**: Pages with titles containing "架构", "拓扑", "技术方案", "系统概览", "Architecture", "Topology", or any complex technical structure visualization.
|
|
127
|
-
|
|
128
|
-
> ⚠️ **This is the skill's signature capability.** Architecture diagrams are ALWAYS generated via `image_gen.py`, regardless of Tier selection (Tier 1/2/3) or scenario (bid/free/template). They are never skipped.
|
|
129
|
-
|
|
130
|
-
| Key Point | Description |
|
|
131
|
-
|-----------|-------------|
|
|
132
|
-
| Light color scheme | Prefer light/pastel tones matching PPT palette |
|
|
133
|
-
| **No text in image** | Never include any text, labels, or words — text is rendered as SVG `<text>` elements on top |
|
|
134
|
-
| Abstract/conceptual | Show interconnected modules, flowing data paths, layered structures |
|
|
135
|
-
| Professional style | Enterprise-grade, clean, not cartoonish |
|
|
136
|
-
| Semi-transparent usage | Typically used at 20-40% opacity as background layer behind SVG text |
|
|
137
|
-
|
|
138
|
-
**Template**: `Light colored abstract {architecture_type} architecture concept, interconnected modules and components floating in soft gradient space, {theme_elements} connected by flowing light lines, clean minimal style, soft {primary_color} and light gray tones with subtle {accent_color} accents, no text no labels no words no numbers, pastel background, professional enterprise {domain} visualization, 16:9 aspect ratio`
|
|
139
|
-
|
|
140
|
-
**Negative prompt**: `text, letters, words, numbers, labels, annotations, watermark, dark background, dark colors, busy patterns, cartoon, clipart`
|
|
141
|
-
|
|
142
|
-
**SVG Integration**: Architecture diagram images are embedded as background layers:
|
|
143
|
-
```xml
|
|
144
|
-
<image href="../images/{arch_name}.png" x="0" y="80" width="1280" height="600" opacity="0.25"/>
|
|
145
|
-
<!-- SVG text elements rendered on top -->
|
|
146
|
-
<text x="640" y="200" font-size="28" font-weight="bold" text-anchor="middle">Architecture Title</text>
|
|
147
|
-
```
|
|
148
|
-
|
|
149
123
|
### 3.1 Background
|
|
150
124
|
|
|
151
125
|
**Identifying characteristics**: Full-page background for covers or chapter pages; must support text overlay
|
|
@@ -156,69 +130,10 @@ Full directive: "color palette: deep navy blue (#1E3A5F), light gray (#F8F9FA),
|
|
|
156
130
|
| Reserve text area | `negative space in center for text overlay` |
|
|
157
131
|
| Avoid strong subjects | Use abstract, gradient, geometric elements |
|
|
158
132
|
| Low-contrast details | `subtle`, `soft`, `muted` |
|
|
159
|
-
| **Light color scheme** | Prefer light/pastel tones; avoid dark backgrounds |
|
|
160
|
-
| **No text in image** | Never include any text, letters, or words in generated images |
|
|
161
|
-
|
|
162
|
-
**Template**: `Abstract {theme element} background, {style} style, light {primary color} to soft {secondary color} gradient, subtle {decorative elements}, clean negative space in center for text overlay, light color palette, pastel tones, {aspect ratio} aspect ratio, high resolution, professional presentation background`
|
|
163
|
-
|
|
164
|
-
**Negative prompt**: `text, letters, words, numbers, watermark, faces, busy patterns, high contrast details, dark background, dark colors, black background`
|
|
165
|
-
|
|
166
|
-
### 3.1.1 Content Page Background (Free Generation Mode Only)
|
|
167
|
-
|
|
168
|
-
**When to use**: Only in free generation mode (non-bid, non-template), and only after **user explicitly confirms** they want AI backgrounds.
|
|
169
|
-
|
|
170
|
-
**⚠️ Requires user confirmation**: Never auto-generate. Ask in Strategist phase and again before execution.
|
|
171
|
-
|
|
172
|
-
**Cost optimization: Category-based reuse** (CRITICAL):
|
|
173
|
-
Instead of generating one image per page, group pages by category and **share one background image per category**:
|
|
174
|
-
|
|
175
|
-
| Category | Matching pages | Prompt keywords |
|
|
176
|
-
|----------|---------------|-----------------|
|
|
177
|
-
| cover | cover, ending | `corporate, modern business, company` |
|
|
178
|
-
| chapter | chapter_* | `section divider, clean transition, minimal` |
|
|
179
|
-
| company | company_*, brand_*, certifications, client_logos | `corporate headquarters, enterprise building` |
|
|
180
|
-
| tech | platform_*, dev_*, function_*, source_*, ai_* | `technology, digital platform, software` |
|
|
181
|
-
| product | asset_*, integration_*, permission_*, i18n_*, multi_* | `product modules, capability, ecosystem` |
|
|
182
|
-
| cases | *_case, *_apps, cpq_*, operation_* | `enterprise partnership, factory, industry` |
|
|
183
|
-
| service | tech_support, knowledge_*, sla_*, custom_*, strategic_*, ecosystem | `customer service, support center` |
|
|
184
|
-
| delivery | org_*, implementation_*, core_team, pm_*, after_sales | `project management, teamwork, office` |
|
|
185
|
-
|
|
186
|
-
**Result**: 55-page PPT → only **6~8 images** generated (85%+ cost saving).
|
|
187
|
-
|
|
188
|
-
**Skip these pages** (already have rich visuals):
|
|
189
|
-
- Pages generated by `arch_diagram.py` (architecture diagrams)
|
|
190
|
-
- Table of contents page
|
|
191
|
-
|
|
192
|
-
**Key rules**:
|
|
193
|
-
| Rule | Description |
|
|
194
|
-
|------|-------------|
|
|
195
|
-
| **Color matching** | Must match PPT theme — primary blue → light blue-gray tones |
|
|
196
|
-
| **Ultra-low opacity** | Embed at `opacity="0.15"` to `opacity="0.25"` |
|
|
197
|
-
| **No text ever** | No text, numbers, labels in generated images |
|
|
198
|
-
| **Soft & subtle** | `subtle`, `soft`, `muted`, `ethereal` — non-distracting |
|
|
199
|
-
|
|
200
|
-
**Template**: `Light pastel abstract {category_keywords}, soft gradient, subtle {primary_color_name} tones, ethereal, professional business, no text no words, minimal clean, 16:9`
|
|
201
|
-
|
|
202
|
-
**Negative prompt**: `text, letters, words, numbers, labels, annotations, watermark, dark background, dark colors, high contrast, busy patterns, faces, people`
|
|
203
|
-
|
|
204
|
-
**SVG integration** (first child after `<svg>` opening tag):
|
|
205
|
-
```xml
|
|
206
|
-
<image href="../images/{category}_bg.png" x="0" y="0" width="1280" height="720" opacity="0.18"/>
|
|
207
|
-
```
|
|
208
133
|
|
|
209
|
-
**
|
|
210
|
-
1. After all SVGs generated, classify pages into categories (see table above)
|
|
211
|
-
2. **Check global resource library first**: `${SKILL_DIR}/resources/backgrounds/` — if a matching `{category}_bg.png` exists, copy it to project `images/` directly (zero API calls)
|
|
212
|
-
3. Only for missing categories: report to user "Need to generate N new backgrounds (M reused from library). Proceed?"
|
|
213
|
-
4. After confirmation, generate missing images; **save to BOTH project `images/` AND `resources/backgrounds/`** (so future projects can reuse)
|
|
214
|
-
5. Inject `<image>` tag into all SVGs of that category
|
|
215
|
-
6. Run `finalize_svg.py` (auto-embeds as base64)
|
|
134
|
+
**Template**: `Abstract {theme element} background, {style} style, {primary color} to {secondary color} gradient, subtle {decorative elements}, clean negative space in center for text overlay, {aspect ratio} aspect ratio, high resolution, professional presentation background`
|
|
216
135
|
|
|
217
|
-
**
|
|
218
|
-
- This is a **cross-project shared library**, not tied to any single project
|
|
219
|
-
- Every generated background is archived here for future reuse
|
|
220
|
-
- `index.json` tracks metadata (prompt, color tone, suitable scenarios)
|
|
221
|
-
- Over time, the library grows — new projects need fewer (or zero) API calls
|
|
136
|
+
**Negative prompt**: `text, letters, watermark, faces, busy patterns, high contrast details`
|
|
222
137
|
|
|
223
138
|
### 3.2 Photography
|
|
224
139
|
|
|
@@ -438,8 +353,7 @@ Abstract futuristic background with flowing digital waves...
|
|
|
438
353
|
|
|
439
354
|
| Type | Recommended Negative Prompt |
|
|
440
355
|
|------|---------------------------|
|
|
441
|
-
|
|
|
442
|
-
| Background | `text, letters, words, numbers, watermark, faces, busy patterns, high contrast details, dark background, dark colors` |
|
|
356
|
+
| Background | `text, letters, watermark, faces, busy patterns, high contrast details` |
|
|
443
357
|
| Photography | `watermark, text overlay, artificial, CGI, illustration, cartoon, distorted faces` |
|
|
444
358
|
| Illustration | `realistic, photography, 3D render, complex textures, watermark` |
|
|
445
359
|
| Diagram | `cluttered, messy, overlapping elements, dark background, realistic` |
|
|
@@ -447,7 +361,7 @@ Abstract futuristic background with flowing digital waves...
|
|
|
447
361
|
|
|
448
362
|
### Universal Negative Prompts
|
|
449
363
|
|
|
450
|
-
- **Standard**: `text, watermark, signature, blurry, distorted, low quality
|
|
364
|
+
- **Standard**: `text, watermark, signature, blurry, distorted, low quality`
|
|
451
365
|
- **Extended** (people scenarios): `text, watermark, signature, blurry, low quality, distorted, extra fingers, mutated hands, poorly drawn face, bad anatomy, extra limbs, disfigured, deformed`
|
|
452
366
|
|
|
453
367
|
---
|
|
@@ -458,9 +372,8 @@ Abstract futuristic background with flowing digital waves...
|
|
|
458
372
|
|
|
459
373
|
| Purpose | Default Inference |
|
|
460
374
|
|---------|------------------|
|
|
461
|
-
|
|
|
462
|
-
|
|
|
463
|
-
| Chapter page background | Clean geometric pattern, light/pastel colors, no text |
|
|
375
|
+
| Cover background | Abstract gradient background, reserve central text area |
|
|
376
|
+
| Chapter page background | Clean geometric pattern, monochrome focus |
|
|
464
377
|
| Team introduction page | Team collaboration scene illustration (flat style) |
|
|
465
378
|
| Data display page | Clean geometric pattern or solid color background |
|
|
466
379
|
| Product showcase | Product photography style, white or gradient background |
|
|
@@ -144,17 +144,14 @@ Selection principle: Font size is based on **content density**, not design style
|
|
|
144
144
|
|
|
145
145
|
### h. Image Usage Confirmation
|
|
146
146
|
|
|
147
|
-
> **图片生成能力已就绪**(AIGW Gemini 后端)。推荐选择 B(增强模式),在纯 SVG 基础上为封面、结尾等关键页面增加 AI 生成的背景图,提升视觉品质。
|
|
148
|
-
|
|
149
147
|
| Option | Approach | Suitable Scenarios |
|
|
150
148
|
|--------|----------|-------------------|
|
|
151
|
-
| **A** | No images
|
|
152
|
-
| **B
|
|
153
|
-
| **C** |
|
|
154
|
-
| **D** |
|
|
155
|
-
| **E** | Placeholders | 图片后续补充 |
|
|
149
|
+
| **A** | No images | Data reports, process documentation |
|
|
150
|
+
| **B** | User-provided | Has existing image assets |
|
|
151
|
+
| **C** | AI-generated | Custom illustrations, backgrounds needed |
|
|
152
|
+
| **D** | Placeholders | Images to be added later |
|
|
156
153
|
|
|
157
|
-
**When selection includes
|
|
154
|
+
**When selection includes B**, you must run `python3 scripts/analyze_images.py <project_path>/images` before outputting the spec, and integrate scan results into the image resource list.
|
|
158
155
|
|
|
159
156
|
**When B/C/D is selected**, add an image resource list to the spec:
|
|
160
157
|
|
|
@@ -28,7 +28,7 @@ python3 scripts/svg_to_pptx.py <project_path> -s final
|
|
|
28
28
|
| Area | Primary scripts | Documentation |
|
|
29
29
|
|------|-----------------|---------------|
|
|
30
30
|
| Conversion | `pdf_to_md.py`, `doc_to_md.py`, `web_to_md.py`, `web_to_md.cjs` | [docs/conversion.md](./docs/conversion.md) |
|
|
31
|
-
| Project management | `project_manager.py`, `
|
|
31
|
+
| Project management | `project_manager.py`, `batch_validate.py`, `generate_examples_index.py`, `error_helper.py` | [docs/project.md](./docs/project.md) |
|
|
32
32
|
| SVG pipeline | `finalize_svg.py`, `svg_to_pptx.py`, `total_md_split.py`, `svg_quality_checker.py` | [docs/svg-pipeline.md](./docs/svg-pipeline.md) |
|
|
33
33
|
| Image tools | `image_gen.py`, `analyze_images.py`, `gemini_watermark_remover.py` | [docs/image.md](./docs/image.md) |
|
|
34
34
|
| Troubleshooting | validation, preview, export, dependency issues | [docs/troubleshooting.md](./docs/troubleshooting.md) |
|
|
@@ -238,20 +238,6 @@ def finalize_project(
|
|
|
238
238
|
|
|
239
239
|
def main() -> None:
|
|
240
240
|
"""Run the CLI entry point."""
|
|
241
|
-
try:
|
|
242
|
-
_main_impl()
|
|
243
|
-
except KeyboardInterrupt:
|
|
244
|
-
print("\nInterrupted by user.")
|
|
245
|
-
sys.exit(130)
|
|
246
|
-
except SystemExit:
|
|
247
|
-
raise
|
|
248
|
-
except Exception as e:
|
|
249
|
-
safe_print(f"[ERROR] Fatal error: {type(e).__name__}: {e}")
|
|
250
|
-
sys.exit(1)
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
def _main_impl() -> None:
|
|
254
|
-
"""Internal implementation of main CLI logic."""
|
|
255
241
|
parser = argparse.ArgumentParser(
|
|
256
242
|
description='PPT Master - SVG Post-processing Tool',
|
|
257
243
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
@@ -89,18 +89,6 @@ class SVGQualityChecker:
|
|
|
89
89
|
# 5. Check text wrapping methods
|
|
90
90
|
self._check_text_elements(content, result)
|
|
91
91
|
|
|
92
|
-
# 6. Check text overflow (beyond viewBox boundaries)
|
|
93
|
-
self._check_text_overflow(content, result)
|
|
94
|
-
|
|
95
|
-
# 7. Check bottom red line presence
|
|
96
|
-
self._check_bottom_line(content, result)
|
|
97
|
-
|
|
98
|
-
# 8. Check file size (warn if too large)
|
|
99
|
-
file_size = svg_path.stat().st_size
|
|
100
|
-
if file_size > 5 * 1024 * 1024: # 5MB
|
|
101
|
-
result['warnings'].append(f"Large SVG file: {file_size // 1024}KB (may slow down export)")
|
|
102
|
-
result['info']['file_size_kb'] = file_size // 1024
|
|
103
|
-
|
|
104
92
|
# Determine pass/fail
|
|
105
93
|
result['passed'] = len(result['errors']) == 0
|
|
106
94
|
|
|
@@ -218,13 +206,7 @@ class SVGQualityChecker:
|
|
|
218
206
|
if re.search(r'<g[^>]*\sopacity\s*=', content_lower):
|
|
219
207
|
result['errors'].append("Detected forbidden <g opacity> (set opacity on each child element individually)")
|
|
220
208
|
if re.search(r'<image[^>]*\sopacity\s*=', content_lower):
|
|
221
|
-
|
|
222
|
-
# Only flag non-background images with opacity
|
|
223
|
-
image_opacity_matches = re.findall(r'<image[^>]*\sopacity\s*=\s*"([^"]*)"[^>]*/?\s*>', content, re.IGNORECASE)
|
|
224
|
-
bg_pattern = re.search(r'<svg[^>]*>\s*\n?\s*<image[^>]*opacity', content, re.IGNORECASE)
|
|
225
|
-
non_bg_opacity_count = len(image_opacity_matches) - (1 if bg_pattern else 0)
|
|
226
|
-
if non_bg_opacity_count > 0:
|
|
227
|
-
result['errors'].append(f"Detected {non_bg_opacity_count} non-background <image opacity> (use overlay mask approach)")
|
|
209
|
+
result['errors'].append("Detected forbidden <image opacity> (use overlay mask approach)")
|
|
228
210
|
|
|
229
211
|
def _check_fonts(self, content: str, result: Dict):
|
|
230
212
|
"""Check font usage"""
|
|
@@ -286,71 +268,6 @@ class SVGQualityChecker:
|
|
|
286
268
|
f"Detected {len(text_matches)} potentially overly long single-line text(s) (consider using tspan for wrapping)"
|
|
287
269
|
)
|
|
288
270
|
|
|
289
|
-
def _check_text_overflow(self, content: str, result: Dict):
|
|
290
|
-
"""Check if text elements extend beyond viewBox boundaries"""
|
|
291
|
-
# Get viewBox dimensions
|
|
292
|
-
viewbox_match = re.search(r'viewBox="0 0 (\d+) (\d+)"', content)
|
|
293
|
-
if not viewbox_match:
|
|
294
|
-
return
|
|
295
|
-
vb_width = int(viewbox_match.group(1))
|
|
296
|
-
vb_height = int(viewbox_match.group(2))
|
|
297
|
-
|
|
298
|
-
overflow_count = 0
|
|
299
|
-
|
|
300
|
-
# Check <text> x/y coordinates
|
|
301
|
-
for m in re.finditer(r'<text[^>]*\bx="([^"]*)"[^>]*\by="([^"]*)"', content):
|
|
302
|
-
try:
|
|
303
|
-
x = float(m.group(1))
|
|
304
|
-
y = float(m.group(2))
|
|
305
|
-
if x < -10 or x > vb_width + 10:
|
|
306
|
-
overflow_count += 1
|
|
307
|
-
if y < -10 or y > vb_height + 50: # allow small bottom overflow for descenders
|
|
308
|
-
overflow_count += 1
|
|
309
|
-
except (ValueError, TypeError):
|
|
310
|
-
pass
|
|
311
|
-
|
|
312
|
-
# Check <tspan> y coordinates for vertical overflow
|
|
313
|
-
for m in re.finditer(r'<tspan[^>]*\by="([^"]*)"', content):
|
|
314
|
-
try:
|
|
315
|
-
y = float(m.group(1))
|
|
316
|
-
if y > vb_height + 20:
|
|
317
|
-
overflow_count += 1
|
|
318
|
-
except (ValueError, TypeError):
|
|
319
|
-
pass
|
|
320
|
-
|
|
321
|
-
if overflow_count > 0:
|
|
322
|
-
result['errors'].append(
|
|
323
|
-
f"Detected {overflow_count} text element(s) potentially overflowing viewBox ({vb_width}x{vb_height})")
|
|
324
|
-
|
|
325
|
-
def _check_bottom_line(self, content: str, result: Dict):
|
|
326
|
-
"""Check for bottom red line (required on every page)"""
|
|
327
|
-
# Look for a rect at y=716 with height=4 and red-ish fill
|
|
328
|
-
has_bottom_line = bool(re.search(
|
|
329
|
-
r'<rect[^>]*y="71[456]"[^>]*height="[3-6]"[^>]*fill="#[Cc]00000"',
|
|
330
|
-
content
|
|
331
|
-
)) or bool(re.search(
|
|
332
|
-
r'<rect[^>]*fill="#[Cc]00000"[^>]*y="71[456]"[^>]*height="[3-6]"',
|
|
333
|
-
content
|
|
334
|
-
))
|
|
335
|
-
# Also check for line at bottom
|
|
336
|
-
if not has_bottom_line:
|
|
337
|
-
has_bottom_line = bool(re.search(
|
|
338
|
-
r'<line[^>]*y1="71[456]"[^>]*y2="71[456]"[^>]*stroke="#[Cc]00000"',
|
|
339
|
-
content
|
|
340
|
-
))
|
|
341
|
-
if not has_bottom_line:
|
|
342
|
-
# More relaxed: any red rect near bottom
|
|
343
|
-
has_bottom_line = bool(re.search(
|
|
344
|
-
r'<rect[^>]*y="7[01]\d"[^>]*fill="#[Cc]00000"',
|
|
345
|
-
content
|
|
346
|
-
))
|
|
347
|
-
|
|
348
|
-
if not has_bottom_line:
|
|
349
|
-
result['warnings'].append("Missing bottom red line (expected <rect y=\"716\" height=\"4\" fill=\"#C00000\"/>)")
|
|
350
|
-
result['info']['has_bottom_line'] = False
|
|
351
|
-
else:
|
|
352
|
-
result['info']['has_bottom_line'] = True
|
|
353
|
-
|
|
354
271
|
def _categorize_issue(self, error_msg: str) -> str:
|
|
355
272
|
"""Categorize issue type"""
|
|
356
273
|
if 'viewBox' in error_msg:
|
|
@@ -507,79 +424,24 @@ class SVGQualityChecker:
|
|
|
507
424
|
print(f"\n[REPORT] Check report exported: {output_file}")
|
|
508
425
|
|
|
509
426
|
|
|
510
|
-
def auto_fix_svg(svg_file: str) -> Dict:
|
|
511
|
-
"""
|
|
512
|
-
Auto-fix common SVG issues.
|
|
513
|
-
Returns dict with fix counts.
|
|
514
|
-
"""
|
|
515
|
-
path = Path(svg_file)
|
|
516
|
-
with open(path, 'r', encoding='utf-8') as f:
|
|
517
|
-
content = f.read()
|
|
518
|
-
|
|
519
|
-
original = content
|
|
520
|
-
fixes = []
|
|
521
|
-
|
|
522
|
-
# Fix 1: Replace rgba() with rgb() + opacity
|
|
523
|
-
rgba_matches = re.findall(r'rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)', content)
|
|
524
|
-
for r, g, b, a in rgba_matches:
|
|
525
|
-
old = f'rgba({r},{g},{b},{a})'
|
|
526
|
-
# Also match with spaces
|
|
527
|
-
content = re.sub(
|
|
528
|
-
rf'rgba\(\s*{r}\s*,\s*{g}\s*,\s*{b}\s*,\s*{re.escape(a)}\s*\)',
|
|
529
|
-
f'rgb({r},{g},{b})',
|
|
530
|
-
content
|
|
531
|
-
)
|
|
532
|
-
fixes.append(f"rgba→rgb: rgba({r},{g},{b},{a})")
|
|
533
|
-
|
|
534
|
-
# Fix 2: Remove <style> blocks
|
|
535
|
-
if '<style' in content.lower():
|
|
536
|
-
content = re.sub(r'<style[^>]*>.*?</style>', '', content, flags=re.DOTALL | re.IGNORECASE)
|
|
537
|
-
fixes.append("Removed <style> block")
|
|
538
|
-
|
|
539
|
-
# Fix 3: Remove class attributes
|
|
540
|
-
if re.search(r'\bclass\s*=\s*"[^"]*"', content):
|
|
541
|
-
content = re.sub(r'\s*class\s*=\s*"[^"]*"', '', content)
|
|
542
|
-
fixes.append("Removed class attributes")
|
|
543
|
-
|
|
544
|
-
# Fix 4: Add missing bottom red line
|
|
545
|
-
has_bottom_line = bool(re.search(r'<rect[^>]*y="7[01]\d"[^>]*fill="#[Cc]00000"', content))
|
|
546
|
-
if not has_bottom_line:
|
|
547
|
-
# Insert before </svg>
|
|
548
|
-
bottom_line = '<rect x="0" y="716" width="1280" height="4" fill="#C00000"/>'
|
|
549
|
-
content = content.replace('</svg>', f'{bottom_line}\n</svg>')
|
|
550
|
-
fixes.append("Added bottom red line")
|
|
551
|
-
|
|
552
|
-
# Fix 5: Remove <g opacity="..."> by moving opacity to children
|
|
553
|
-
g_opacity_matches = re.findall(r'<g\s+opacity="([^"]+)">', content)
|
|
554
|
-
for op in g_opacity_matches:
|
|
555
|
-
# Simple removal of group opacity (conservative — just remove the opacity attr)
|
|
556
|
-
content = re.sub(r'<g\s+opacity="[^"]+"\s*>', '<g>', content, count=1)
|
|
557
|
-
fixes.append(f"Removed <g opacity=\"{op}\">")
|
|
558
|
-
|
|
559
|
-
if content != original:
|
|
560
|
-
with open(path, 'w', encoding='utf-8') as f:
|
|
561
|
-
f.write(content)
|
|
562
|
-
|
|
563
|
-
return {'file': path.name, 'fixes': fixes, 'changed': content != original}
|
|
564
|
-
|
|
565
|
-
|
|
566
427
|
def main() -> None:
|
|
567
428
|
"""Run the CLI entry point."""
|
|
568
429
|
if len(sys.argv) < 2:
|
|
569
430
|
print("PPT Master - SVG Quality Check Tool\n")
|
|
570
431
|
print("Usage:")
|
|
571
|
-
print(" python3 scripts/svg_quality_checker.py <
|
|
572
|
-
print(" python3 scripts/svg_quality_checker.py <directory>
|
|
573
|
-
print(" python3 scripts/svg_quality_checker.py <directory> --fix --check # Fix then re-check")
|
|
432
|
+
print(" python3 scripts/svg_quality_checker.py <svg_file>")
|
|
433
|
+
print(" python3 scripts/svg_quality_checker.py <directory>")
|
|
574
434
|
print(" python3 scripts/svg_quality_checker.py --all examples")
|
|
435
|
+
print("\nExamples:")
|
|
436
|
+
print(" python3 scripts/svg_quality_checker.py examples/project/svg_output/slide_01.svg")
|
|
437
|
+
print(" python3 scripts/svg_quality_checker.py examples/project/svg_output")
|
|
438
|
+
print(" python3 scripts/svg_quality_checker.py examples/project")
|
|
575
439
|
sys.exit(0)
|
|
576
440
|
|
|
577
441
|
checker = SVGQualityChecker()
|
|
578
|
-
do_fix = '--fix' in sys.argv
|
|
579
|
-
do_check_after_fix = '--check' in sys.argv
|
|
580
442
|
|
|
581
443
|
# Parse arguments
|
|
582
|
-
target =
|
|
444
|
+
target = sys.argv[1]
|
|
583
445
|
expected_format = None
|
|
584
446
|
|
|
585
447
|
if '--format' in sys.argv:
|
|
@@ -587,29 +449,6 @@ def main() -> None:
|
|
|
587
449
|
if idx + 1 < len(sys.argv):
|
|
588
450
|
expected_format = sys.argv[idx + 1]
|
|
589
451
|
|
|
590
|
-
# Auto-fix mode
|
|
591
|
-
if do_fix:
|
|
592
|
-
target_path = Path(target)
|
|
593
|
-
if target_path.is_file():
|
|
594
|
-
svg_files = [target_path]
|
|
595
|
-
else:
|
|
596
|
-
svg_output = target_path / 'svg_output' if (target_path / 'svg_output').exists() else target_path
|
|
597
|
-
svg_files = sorted(svg_output.glob('*.svg'))
|
|
598
|
-
|
|
599
|
-
print(f"\n[FIX] Auto-fixing {len(svg_files)} SVG file(s)...\n")
|
|
600
|
-
total_fixes = 0
|
|
601
|
-
for svg_file in svg_files:
|
|
602
|
-
result = auto_fix_svg(str(svg_file))
|
|
603
|
-
if result['changed']:
|
|
604
|
-
total_fixes += len(result['fixes'])
|
|
605
|
-
print(f" [FIXED] {result['file']}: {', '.join(result['fixes'])}")
|
|
606
|
-
print(f"\n[FIX] Total fixes applied: {total_fixes}")
|
|
607
|
-
|
|
608
|
-
if not do_check_after_fix:
|
|
609
|
-
print("\n[TIP] Run with --fix --check to verify fixes")
|
|
610
|
-
sys.exit(0)
|
|
611
|
-
print("\n--- Re-checking after fixes ---\n")
|
|
612
|
-
|
|
613
452
|
# Execute check
|
|
614
453
|
if target == '--all':
|
|
615
454
|
# Check all example projects
|
|
@@ -351,16 +351,10 @@ def create_pptx_with_native_svg(
|
|
|
351
351
|
arcname = file_path.relative_to(extract_dir)
|
|
352
352
|
zf.write(file_path, arcname)
|
|
353
353
|
|
|
354
|
-
failed_count = len(svg_files) - success_count
|
|
355
354
|
if verbose:
|
|
356
355
|
print()
|
|
357
356
|
print(f"[Done] Saved: {output_path}")
|
|
358
|
-
print(f" Succeeded: {success_count}, Failed: {
|
|
359
|
-
if failed_count > 0:
|
|
360
|
-
failed_indices = [i + 1 for i in range(len(svg_files))
|
|
361
|
-
if i + 1 not in range(1, success_count + failed_count + 1)]
|
|
362
|
-
# List failed slides by checking which ones threw exceptions
|
|
363
|
-
print(f" Note: {failed_count} slide(s) failed and were skipped.")
|
|
357
|
+
print(f" Succeeded: {success_count}, Failed: {len(svg_files) - success_count}")
|
|
364
358
|
if use_compat_mode and has_any_image:
|
|
365
359
|
print(f" Mode: Office compatibility mode (supports all Office versions)")
|
|
366
360
|
if PNG_RENDERER == 'svglib' and renderer_hint:
|
|
@@ -15,20 +15,6 @@ from .pptx_slide_xml import TRANSITIONS
|
|
|
15
15
|
|
|
16
16
|
def main() -> None:
|
|
17
17
|
"""CLI entry point for the SVG to PPTX conversion tool."""
|
|
18
|
-
try:
|
|
19
|
-
_main_impl()
|
|
20
|
-
except KeyboardInterrupt:
|
|
21
|
-
print("\nInterrupted by user.")
|
|
22
|
-
sys.exit(130)
|
|
23
|
-
except SystemExit:
|
|
24
|
-
raise
|
|
25
|
-
except Exception as e:
|
|
26
|
-
print(f"Fatal error: {type(e).__name__}: {e}", file=sys.stderr)
|
|
27
|
-
sys.exit(1)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def _main_impl() -> None:
|
|
31
|
-
"""Internal implementation of main CLI logic."""
|
|
32
18
|
transition_choices = (
|
|
33
19
|
['none'] + (list(TRANSITIONS.keys()) if TRANSITIONS
|
|
34
20
|
else ['fade', 'push', 'wipe', 'split', 'strips', 'cover', 'random'])
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Risk Alert - 智能风险预警 Skill
|
|
2
|
+
|
|
3
|
+
## 功能概述
|
|
4
|
+
|
|
5
|
+
自动监控飞书群聊消息,智能识别风险并推送预警卡片。
|
|
6
|
+
|
|
7
|
+
## 首次使用配置
|
|
8
|
+
|
|
9
|
+
### 1. 配置飞书应用凭证
|
|
10
|
+
|
|
11
|
+
需要用户提供飞书自建应用的 `App ID` 和 `App Secret`:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# 方式1:环境变量
|
|
15
|
+
export FEISHU_APP_ID="your_app_id"
|
|
16
|
+
export FEISHU_APP_SECRET="your_app_secret"
|
|
17
|
+
|
|
18
|
+
# 方式2:配置文件(首次运行会自动创建)
|
|
19
|
+
# 编辑 config.json 文件
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 2. 选择监控群聊
|
|
23
|
+
|
|
24
|
+
首次运行时会自动获取机器人加入的所有群聊,并展示列表让用户确认:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
📋 发现机器人已加入以下群聊:
|
|
28
|
+
1. 项目群A (oc_xxx1)
|
|
29
|
+
2. 项目群B (oc_xxx2)
|
|
30
|
+
3. 测试群 (oc_xxx3)
|
|
31
|
+
|
|
32
|
+
请选择要监控的群聊(输入序号,多个用逗号分隔,输入 all 选择全部):
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 3. 选择推送目标
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
请选择风险预警推送目标:
|
|
39
|
+
1. 推送到指定群聊
|
|
40
|
+
2. 推送到指定用户
|
|
41
|
+
3. 同时推送
|
|
42
|
+
|
|
43
|
+
请输入选择(1/2/3):
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 4. 保存配置
|
|
47
|
+
|
|
48
|
+
配置会自动保存到 `config.json`,后续运行直接使用已保存的配置。
|
|
49
|
+
|
|
50
|
+
## 使用方法
|
|
51
|
+
|
|
52
|
+
### 手动执行
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# 进入 skill 目录
|
|
56
|
+
cd /Users/song/.openclaw/workspace/skills/risk-alert
|
|
57
|
+
|
|
58
|
+
# 执行完整流程
|
|
59
|
+
node scripts/risk-alert.js
|
|
60
|
+
|
|
61
|
+
# 仅抓取消息
|
|
62
|
+
node scripts/analyze-risk.js
|
|
63
|
+
|
|
64
|
+
# 仅推送卡片(AI 分析完成后)
|
|
65
|
+
node scripts/push-beautiful.js
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 通过触发器
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# 发送触发指令给 AI
|
|
72
|
+
./trigger-risk-alert.sh
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## 工作流程
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
1. 抓取群聊消息 → raw-messages.json
|
|
79
|
+
2. AI 智能分析 → risk-data.json
|
|
80
|
+
3. 推送预警卡片 → 飞书
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 配置项说明
|
|
84
|
+
|
|
85
|
+
| 配置项 | 说明 | 必填 |
|
|
86
|
+
|--------|------|------|
|
|
87
|
+
| appId | 飞书应用 ID | 是 |
|
|
88
|
+
| appSecret | 飞书应用 Secret | 是 |
|
|
89
|
+
| monitoredChats | 监控的群聊列表 | 是 |
|
|
90
|
+
| pushTarget.type | 推送类型: chat/user/both | 是 |
|
|
91
|
+
| pushTarget.chatId | 推送群聊 ID | 条件必填 |
|
|
92
|
+
| pushTarget.userId | 推送用户 ID | 条件必填 |
|
|
93
|
+
| days | 首次拉取天数 | 否,默认7 |
|
|
94
|
+
|
|
95
|
+
## 文件结构
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
risk-alert/
|
|
99
|
+
├── SKILL.md # 本文件
|
|
100
|
+
├── config.json # 用户配置(首次运行生成)
|
|
101
|
+
├── trigger-risk-alert.sh # 触发脚本
|
|
102
|
+
├── scheduler.sh # 定时任务
|
|
103
|
+
└── scripts/
|
|
104
|
+
├── analyze-risk.js # 消息抓取
|
|
105
|
+
├── risk-alert.js # 流程控制
|
|
106
|
+
├── push-beautiful.js # 卡片推送
|
|
107
|
+
├── config-manager.js # 配置管理
|
|
108
|
+
└── lib/
|
|
109
|
+
└── feishu-api.js # 飞书 API 封装
|
|
110
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"feishu": {
|
|
3
|
+
"appId": "YOUR_APP_ID_HERE",
|
|
4
|
+
"appSecret": "YOUR_APP_SECRET_HERE"
|
|
5
|
+
},
|
|
6
|
+
"monitoredChats": [
|
|
7
|
+
{
|
|
8
|
+
"id": "oc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
9
|
+
"name": "群聊名称"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"pushTarget": {
|
|
13
|
+
"type": "chat",
|
|
14
|
+
"chatId": "oc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
15
|
+
"userId": ""
|
|
16
|
+
},
|
|
17
|
+
"settings": {
|
|
18
|
+
"days": 7,
|
|
19
|
+
"incrementMode": true
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Risk Alert 定时推送脚本
|
|
3
|
+
# 每20分钟执行一次
|
|
4
|
+
|
|
5
|
+
# 设置 PATH(launchd 环境变量不同)
|
|
6
|
+
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
|
|
7
|
+
|
|
8
|
+
# 查找 node 路径
|
|
9
|
+
NODE_PATH=$(which node)
|
|
10
|
+
if [ -z "$NODE_PATH" ]; then
|
|
11
|
+
# 尝试常见路径
|
|
12
|
+
if [ -f "/usr/local/bin/node" ]; then
|
|
13
|
+
NODE_PATH="/usr/local/bin/node"
|
|
14
|
+
elif [ -f "/opt/homebrew/bin/node" ]; then
|
|
15
|
+
NODE_PATH="/opt/homebrew/bin/node"
|
|
16
|
+
elif [ -f "$HOME/.nvm/versions/node/v22.18.0/bin/node" ]; then
|
|
17
|
+
NODE_PATH="$HOME/.nvm/versions/node/v22.18.0/bin/node"
|
|
18
|
+
fi
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# 工作目录
|
|
22
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
cd "$SCRIPT_DIR/scripts"
|
|
24
|
+
|
|
25
|
+
# 日志文件
|
|
26
|
+
LOG_FILE="$SCRIPT_DIR/risk-alert.log"
|
|
27
|
+
|
|
28
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始执行 Risk Alert 定时任务" >> "$LOG_FILE"
|
|
29
|
+
|
|
30
|
+
# Step 1: 全量抓取消息(删除状态文件)
|
|
31
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 步骤1: 抓取消息..." >> "$LOG_FILE"
|
|
32
|
+
rm -f last-fetch-state.json
|
|
33
|
+
$NODE_PATH analyze-risk.js >> "$LOG_FILE" 2>&1
|
|
34
|
+
if [ $? -ne 0 ]; then
|
|
35
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ❌ 消息抓取失败" >> "$LOG_FILE"
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# 检查是否有新消息
|
|
40
|
+
if [ -f "raw-messages.json" ]; then
|
|
41
|
+
NEW_COUNT=$($NODE_PATH -e "console.log(JSON.parse(require('fs').readFileSync('raw-messages.json')).newMessagesCount || 0)")
|
|
42
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 新增消息: $NEW_COUNT 条" >> "$LOG_FILE"
|
|
43
|
+
|
|
44
|
+
if [ "$NEW_COUNT" -eq 0 ]; then
|
|
45
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ℹ️ 没有新消息,跳过分析" >> "$LOG_FILE"
|
|
46
|
+
# 仍然推送一次(显示无风险状态)
|
|
47
|
+
$NODE_PATH push-beautiful.js >> "$LOG_FILE" 2>&1
|
|
48
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✅ 已推送无风险状态卡片" >> "$LOG_FILE"
|
|
49
|
+
exit 0
|
|
50
|
+
fi
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Step 2: 生成 AI 任务文件
|
|
54
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 步骤2: 生成 AI 分析任务..." >> "$LOG_FILE"
|
|
55
|
+
$NODE_PATH risk-alert.js >> "$LOG_FILE" 2>&1
|
|
56
|
+
|
|
57
|
+
# Step 3: 调用 AI 分析(通过发送消息触发)
|
|
58
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 步骤3: 等待 AI 分析..." >> "$LOG_FILE"
|
|
59
|
+
echo "请 AI 助手执行风险分析并生成 risk-data.json,然后执行: node risk-alert.js push"
|
|
60
|
+
|
|
61
|
+
# 注意:AI 分析需要手动触发或由 AI 自动处理
|
|
62
|
+
# 这里我们直接推送(假设 AI 已经完成分析或 risk-data.json 已存在)
|
|
63
|
+
|
|
64
|
+
# Step 4: 推送卡片
|
|
65
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 步骤4: 推送卡片..." >> "$LOG_FILE"
|
|
66
|
+
$NODE_PATH risk-alert.js push >> "$LOG_FILE" 2>&1
|
|
67
|
+
if [ $? -eq 0 ]; then
|
|
68
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✅ 推送成功" >> "$LOG_FILE"
|
|
69
|
+
else
|
|
70
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ❌ 推送失败" >> "$LOG_FILE"
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 定时任务执行完毕" >> "$LOG_FILE"
|
|
74
|
+
echo "---" >> "$LOG_FILE"
|