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.
Files changed (221) hide show
  1. package/bin/install-lib.mjs +11 -0
  2. package/bin/install.mjs +59 -1
  3. package/package.json +12 -1
  4. package/skills/acceptance-doc-entry/SKILL.md +54 -1
  5. package/skills/ppt-master/SKILL.md +17 -390
  6. package/skills/ppt-master/projects/.gitkeep +0 -0
  7. package/skills/ppt-master/references/executor-base.md +4 -3
  8. package/skills/ppt-master/references/image-generator.md +6 -93
  9. package/skills/ppt-master/references/strategist.md +5 -8
  10. package/skills/ppt-master/scripts/README.md +1 -1
  11. package/skills/ppt-master/scripts/finalize_svg.py +0 -14
  12. package/skills/ppt-master/scripts/svg_quality_checker.py +8 -169
  13. package/skills/ppt-master/scripts/svg_to_pptx/pptx_builder.py +1 -7
  14. package/skills/ppt-master/scripts/svg_to_pptx/pptx_cli.py +0 -14
  15. package/skills/risk-alert/SKILL.md +110 -0
  16. package/skills/risk-alert/config.example.json +21 -0
  17. package/skills/risk-alert/scheduler.sh +74 -0
  18. package/skills/risk-alert/scripts/analyze-risk.js +414 -0
  19. package/skills/risk-alert/scripts/config-manager.js +241 -0
  20. package/skills/risk-alert/scripts/push-beautiful.js +225 -0
  21. package/skills/risk-alert/scripts/risk-alert.js +136 -0
  22. package/skills/risk-alert/scripts/run-full.js +60 -0
  23. package/skills/risk-alert/trigger-risk-alert.sh +35 -0
  24. package/skills/ppt-master/.env.example +0 -35
  25. package/skills/ppt-master/README.md +0 -90
  26. package/skills/ppt-master/audit_report_model_perf.md +0 -213
  27. package/skills/ppt-master/audit_report_portability.md +0 -90
  28. package/skills/ppt-master/audit_report_robustness.md +0 -192
  29. package/skills/ppt-master/audit_report_workflow.md +0 -233
  30. package/skills/ppt-master/fix_report_bid.md +0 -51
  31. package/skills/ppt-master/fix_report_scripts.md +0 -41
  32. package/skills/ppt-master/references/bid-content-example-netease.md +0 -815
  33. package/skills/ppt-master/references/bid-content-template.md +0 -390
  34. package/skills/ppt-master/references/bid-example-netease.md +0 -339
  35. package/skills/ppt-master/references/bid-presentation.md +0 -384
  36. package/skills/ppt-master/references/bid-svgs/03_toc.svg +0 -38
  37. package/skills/ppt-master/references/bid-svgs/04_chapter_company.svg +0 -7
  38. package/skills/ppt-master/references/bid-svgs/05_company_overview.svg +0 -28
  39. package/skills/ppt-master/references/bid-svgs/06_vision_business.svg +0 -45
  40. package/skills/ppt-master/references/bid-svgs/07_product_system.svg +0 -52
  41. package/skills/ppt-master/references/bid-svgs/08_codewave_timeline.svg +0 -29
  42. package/skills/ppt-master/references/bid-svgs/09_certifications.svg +0 -33
  43. package/skills/ppt-master/references/bid-svgs/10_client_logos.svg +0 -25
  44. package/skills/ppt-master/references/bid-svgs/11_brand_mission.svg +0 -14
  45. package/skills/ppt-master/references/bid-svgs/12_chapter_demand.svg +0 -7
  46. package/skills/ppt-master/references/bid-svgs/16_chapter_advantages.svg +0 -7
  47. package/skills/ppt-master/references/bid-svgs/18_platform_arch.svg +0 -24
  48. package/skills/ppt-master/references/bid-svgs/19_function_matrix.svg +0 -35
  49. package/skills/ppt-master/references/bid-svgs/20_dev_arch.svg +0 -29
  50. package/skills/ppt-master/references/bid-svgs/21_source_code.svg +0 -25
  51. package/skills/ppt-master/references/bid-svgs/22_ai_dev.svg +0 -27
  52. package/skills/ppt-master/references/bid-svgs/23_asset_market.svg +0 -33
  53. package/skills/ppt-master/references/bid-svgs/24_multi_org.svg +0 -28
  54. package/skills/ppt-master/references/bid-svgs/25_i18n.svg +0 -22
  55. package/skills/ppt-master/references/bid-svgs/26_multi_tenant.svg +0 -25
  56. package/skills/ppt-master/references/bid-svgs/27_integration.svg +0 -27
  57. package/skills/ppt-master/references/bid-svgs/28_permission.svg +0 -31
  58. package/skills/ppt-master/references/bid-svgs/29_security.svg +0 -25
  59. package/skills/ppt-master/references/bid-svgs/30_ai_capabilities.svg +0 -21
  60. package/skills/ppt-master/references/bid-svgs/31_product_combo.svg +0 -25
  61. package/skills/ppt-master/references/bid-svgs/32_digital_transform.svg +0 -28
  62. package/skills/ppt-master/references/bid-svgs/33_chapter_cases.svg +0 -7
  63. package/skills/ppt-master/references/bid-svgs/34_cummins_case.svg +0 -23
  64. package/skills/ppt-master/references/bid-svgs/35_cpq_cost.svg +0 -22
  65. package/skills/ppt-master/references/bid-svgs/36_tech_platform.svg +0 -18
  66. package/skills/ppt-master/references/bid-svgs/37_platform_value.svg +0 -24
  67. package/skills/ppt-master/references/bid-svgs/38_operation_plan.svg +0 -25
  68. package/skills/ppt-master/references/bid-svgs/39_zpmc_case.svg +0 -21
  69. package/skills/ppt-master/references/bid-svgs/40_zpmc_apps.svg +0 -23
  70. package/skills/ppt-master/references/bid-svgs/41_chapter_service.svg +0 -7
  71. package/skills/ppt-master/references/bid-svgs/42_tech_support.svg +0 -24
  72. package/skills/ppt-master/references/bid-svgs/43_knowledge_transfer.svg +0 -25
  73. package/skills/ppt-master/references/bid-svgs/44_operation_promotion.svg +0 -20
  74. package/skills/ppt-master/references/bid-svgs/45_custom_dev_guide.svg +0 -24
  75. package/skills/ppt-master/references/bid-svgs/46_sla_guarantee.svg +0 -18
  76. package/skills/ppt-master/references/bid-svgs/47_strategic_cooperation.svg +0 -25
  77. package/skills/ppt-master/references/bid-svgs/48_ecosystem.svg +0 -24
  78. package/skills/ppt-master/references/bid-svgs/49_chapter_delivery.svg +0 -23
  79. package/skills/ppt-master/references/bid-svgs/53_pm_intro.svg +0 -24
  80. package/skills/ppt-master/references/bid-svgs/54_after_sales.svg +0 -27
  81. package/skills/ppt-master/references/bid-svgs/55_ending.svg +0 -8
  82. package/skills/ppt-master/references/company_intro.md +0 -93
  83. package/skills/ppt-master/references/company_intro_images/slide1_img00.png +0 -0
  84. package/skills/ppt-master/references/company_intro_images/slide1_img01.png +0 -0
  85. package/skills/ppt-master/references/company_intro_images/slide1_img02.png +0 -0
  86. package/skills/ppt-master/references/company_intro_images/slide1_img03.png +0 -0
  87. package/skills/ppt-master/references/company_intro_images/slide1_img04.png +0 -0
  88. package/skills/ppt-master/references/company_intro_images/slide1_img05.png +0 -0
  89. package/skills/ppt-master/references/company_intro_images/slide1_img06.png +0 -0
  90. package/skills/ppt-master/references/company_intro_images/slide1_img07.png +0 -0
  91. package/skills/ppt-master/references/company_intro_images/slide1_img08.png +0 -0
  92. package/skills/ppt-master/references/company_intro_images/slide1_img09.png +0 -0
  93. package/skills/ppt-master/references/company_intro_images/slide1_img10.png +0 -0
  94. package/skills/ppt-master/references/company_intro_images/slide1_img11.png +0 -0
  95. package/skills/ppt-master/references/company_intro_images/slide1_img12.png +0 -0
  96. package/skills/ppt-master/references/company_intro_images/slide1_img13.png +0 -0
  97. package/skills/ppt-master/references/company_intro_images/slide1_img14.png +0 -0
  98. package/skills/ppt-master/references/company_intro_images/slide1_img15.png +0 -0
  99. package/skills/ppt-master/references/company_intro_images/slide1_img16.png +0 -0
  100. package/skills/ppt-master/references/company_intro_images/slide1_img17.png +0 -0
  101. package/skills/ppt-master/references/company_intro_images/slide1_img18.png +0 -0
  102. package/skills/ppt-master/references/company_intro_images/slide1_img19.png +0 -0
  103. package/skills/ppt-master/references/company_intro_images/slide1_img20.png +0 -0
  104. package/skills/ppt-master/references/company_intro_images/slide1_img21.png +0 -0
  105. package/skills/ppt-master/references/company_intro_images/slide1_img22.png +0 -0
  106. package/skills/ppt-master/references/company_intro_images/slide1_img23.png +0 -0
  107. package/skills/ppt-master/references/company_intro_images/slide1_img24.png +0 -0
  108. package/skills/ppt-master/references/company_intro_images/slide1_img25.png +0 -0
  109. package/skills/ppt-master/references/company_intro_images/slide1_img26.png +0 -0
  110. package/skills/ppt-master/references/company_intro_images/slide1_img27.png +0 -0
  111. package/skills/ppt-master/references/company_intro_images/slide1_img28.png +0 -0
  112. package/skills/ppt-master/references/company_intro_images/slide1_img29.png +0 -0
  113. package/skills/ppt-master/references/company_intro_images/slide2_img30.png +0 -0
  114. package/skills/ppt-master/references/company_intro_images/slide2_img31.jpg +0 -0
  115. package/skills/ppt-master/references/company_intro_images/slide3_img32.png +0 -0
  116. package/skills/ppt-master/references/company_intro_images/slide3_img33.png +0 -0
  117. package/skills/ppt-master/references/drawio-integration.md +0 -144
  118. package/skills/ppt-master/requirements.txt +0 -19
  119. package/skills/ppt-master/resources/backgrounds/chapter_bg.png +0 -0
  120. package/skills/ppt-master/resources/backgrounds/company_bg.png +0 -0
  121. package/skills/ppt-master/resources/backgrounds/cover_bg.png +0 -0
  122. package/skills/ppt-master/resources/backgrounds/index.json +0 -40
  123. package/skills/ppt-master/resources/backgrounds/tech_bg.png +0 -0
  124. package/skills/ppt-master/scripts/__pycache__/config.cpython-314.pyc +0 -0
  125. package/skills/ppt-master/scripts/__pycache__/error_helper.cpython-314.pyc +0 -0
  126. package/skills/ppt-master/scripts/__pycache__/pptx_animations.cpython-314.pyc +0 -0
  127. package/skills/ppt-master/scripts/__pycache__/project_utils.cpython-314.pyc +0 -0
  128. package/skills/ppt-master/scripts/arch_diagram.py +0 -370
  129. package/skills/ppt-master/scripts/bid_init.py +0 -79
  130. package/skills/ppt-master/scripts/drawio_gen.py +0 -366
  131. package/skills/ppt-master/scripts/drawio_to_svg.py +0 -458
  132. package/skills/ppt-master/scripts/image_backends/__pycache__/__init__.cpython-314.pyc +0 -0
  133. package/skills/ppt-master/scripts/image_backends/__pycache__/backend_aigw_gemini.cpython-314.pyc +0 -0
  134. package/skills/ppt-master/scripts/image_backends/__pycache__/backend_common.cpython-314.pyc +0 -0
  135. package/skills/ppt-master/scripts/svg_finalize/__pycache__/__init__.cpython-314.pyc +0 -0
  136. package/skills/ppt-master/scripts/svg_finalize/__pycache__/crop_images.cpython-314.pyc +0 -0
  137. package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_icons.cpython-314.pyc +0 -0
  138. package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_images.cpython-314.pyc +0 -0
  139. package/skills/ppt-master/scripts/svg_finalize/__pycache__/fix_image_aspect.cpython-314.pyc +0 -0
  140. package/skills/ppt-master/scripts/svg_finalize/__pycache__/flatten_tspan.cpython-314.pyc +0 -0
  141. package/skills/ppt-master/scripts/svg_finalize/__pycache__/svg_rect_to_path.cpython-314.pyc +0 -0
  142. package/skills/ppt-master/scripts/svg_page_gen.py +0 -871
  143. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/__init__.cpython-314.pyc +0 -0
  144. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_context.cpython-314.pyc +0 -0
  145. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_converter.cpython-314.pyc +0 -0
  146. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_elements.cpython-314.pyc +0 -0
  147. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_paths.cpython-314.pyc +0 -0
  148. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_styles.cpython-314.pyc +0 -0
  149. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_utils.cpython-314.pyc +0 -0
  150. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_builder.cpython-314.pyc +0 -0
  151. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_cli.cpython-314.pyc +0 -0
  152. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_dimensions.cpython-314.pyc +0 -0
  153. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_discovery.cpython-314.pyc +0 -0
  154. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_media.cpython-314.pyc +0 -0
  155. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_notes.cpython-314.pyc +0 -0
  156. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_slide_xml.cpython-314.pyc +0 -0
  157. /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
  158. /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
  159. /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
  160. /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
  161. /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
  162. /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
  163. /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
  164. /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
  165. /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
  166. /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
  167. /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
  168. /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
  169. /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
  170. /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
  171. /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
  172. /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
  173. /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
  174. /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
  175. /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
  176. /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
  177. /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
  178. /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
  179. /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
  180. /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
  181. /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
  182. /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
  183. /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
  184. /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
  185. /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
  186. /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
  187. /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
  188. /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
  189. /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
  190. /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
  191. /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
  192. /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
  193. /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
  194. /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
  195. /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
  196. /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
  197. /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
  198. /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
  199. /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
  200. /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
  201. /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
  202. /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
  203. /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
  204. /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
  205. /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
  206. /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
  207. /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
  208. /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
  209. /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
  210. /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
  211. /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
  212. /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
  213. /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
  214. /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
  215. /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
  216. /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
  217. /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
  218. /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
  219. /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
  220. /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
  221. /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
- **Workflow**:
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
- **Global Resource Library**: `${SKILL_DIR}/resources/backgrounds/`
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
- | **🌟 Architecture diagram** | `text, letters, words, numbers, labels, annotations, watermark, dark background, dark colors, busy patterns, cartoon, clipart` |
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, letters, words, numbers`
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
- | **🌟 Architecture/topology page** | Light-colored abstract architecture concept, interconnected modules, no text, professional enterprise style |
462
- | Cover background | Light-toned abstract gradient background, no text, reserve central text area |
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 pure SVG visual design | 追求极简/快速出稿;纯渐变+几何+图标 |
152
- | **B (推荐)** | SVG + AI 生成装饰图(封面背景、章节配图) | 专业演示场景,需要视觉冲击力。SVG 结构为主体,图片锦上添花 |
153
- | **C** | SVG + AI 生成全量配图 | 每个受益页面都配图,最高视觉品质,耗时最长 |
154
- | **D** | User-provided images | 已有图片素材 |
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 D**, you must run `python3 scripts/analyze_images.py <project_path>/images` before outputting the spec, and integrate scan results into the image resource list.
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`, `bid_init.py`, `batch_validate.py`, `generate_examples_index.py`, `error_helper.py` | [docs/project.md](./docs/project.md) |
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
- # Allow opacity on background images (first <image> child of <svg>)
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 <svg_file_or_directory>")
572
- print(" python3 scripts/svg_quality_checker.py <directory> --fix # Auto-fix common issues")
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 = [a for a in sys.argv[1:] if not a.startswith('--')][0] if any(not a.startswith('--') for a in sys.argv[1:]) else sys.argv[1]
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: {failed_count}")
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"