codewave-openclaw-installer 2.1.13 → 2.2.1

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 (214) hide show
  1. package/bin/install-lib.mjs +11 -0
  2. package/bin/install.mjs +60 -2
  3. package/index.js +1 -1
  4. package/openclaw.plugin.json +1 -1
  5. package/package.json +12 -1
  6. package/skills/acceptance-doc-entry/SKILL.md +54 -1
  7. package/skills/ppt-master/SKILL.md +17 -390
  8. package/skills/ppt-master/projects/.gitkeep +0 -0
  9. package/skills/ppt-master/references/executor-base.md +4 -3
  10. package/skills/ppt-master/references/image-generator.md +6 -93
  11. package/skills/ppt-master/references/strategist.md +5 -8
  12. package/skills/ppt-master/scripts/README.md +1 -1
  13. package/skills/ppt-master/scripts/finalize_svg.py +0 -14
  14. package/skills/ppt-master/scripts/svg_quality_checker.py +8 -169
  15. package/skills/ppt-master/scripts/svg_to_pptx/pptx_builder.py +1 -7
  16. package/skills/ppt-master/scripts/svg_to_pptx/pptx_cli.py +0 -14
  17. package/skills/ppt-master/.env.example +0 -35
  18. package/skills/ppt-master/README.md +0 -90
  19. package/skills/ppt-master/audit_report_model_perf.md +0 -213
  20. package/skills/ppt-master/audit_report_portability.md +0 -90
  21. package/skills/ppt-master/audit_report_robustness.md +0 -192
  22. package/skills/ppt-master/audit_report_workflow.md +0 -233
  23. package/skills/ppt-master/fix_report_bid.md +0 -51
  24. package/skills/ppt-master/fix_report_scripts.md +0 -41
  25. package/skills/ppt-master/references/bid-content-example-netease.md +0 -815
  26. package/skills/ppt-master/references/bid-content-template.md +0 -390
  27. package/skills/ppt-master/references/bid-example-netease.md +0 -339
  28. package/skills/ppt-master/references/bid-presentation.md +0 -384
  29. package/skills/ppt-master/references/bid-svgs/03_toc.svg +0 -38
  30. package/skills/ppt-master/references/bid-svgs/04_chapter_company.svg +0 -7
  31. package/skills/ppt-master/references/bid-svgs/05_company_overview.svg +0 -28
  32. package/skills/ppt-master/references/bid-svgs/06_vision_business.svg +0 -45
  33. package/skills/ppt-master/references/bid-svgs/07_product_system.svg +0 -52
  34. package/skills/ppt-master/references/bid-svgs/08_codewave_timeline.svg +0 -29
  35. package/skills/ppt-master/references/bid-svgs/09_certifications.svg +0 -33
  36. package/skills/ppt-master/references/bid-svgs/10_client_logos.svg +0 -25
  37. package/skills/ppt-master/references/bid-svgs/11_brand_mission.svg +0 -14
  38. package/skills/ppt-master/references/bid-svgs/12_chapter_demand.svg +0 -7
  39. package/skills/ppt-master/references/bid-svgs/16_chapter_advantages.svg +0 -7
  40. package/skills/ppt-master/references/bid-svgs/18_platform_arch.svg +0 -24
  41. package/skills/ppt-master/references/bid-svgs/19_function_matrix.svg +0 -35
  42. package/skills/ppt-master/references/bid-svgs/20_dev_arch.svg +0 -29
  43. package/skills/ppt-master/references/bid-svgs/21_source_code.svg +0 -25
  44. package/skills/ppt-master/references/bid-svgs/22_ai_dev.svg +0 -27
  45. package/skills/ppt-master/references/bid-svgs/23_asset_market.svg +0 -33
  46. package/skills/ppt-master/references/bid-svgs/24_multi_org.svg +0 -28
  47. package/skills/ppt-master/references/bid-svgs/25_i18n.svg +0 -22
  48. package/skills/ppt-master/references/bid-svgs/26_multi_tenant.svg +0 -25
  49. package/skills/ppt-master/references/bid-svgs/27_integration.svg +0 -27
  50. package/skills/ppt-master/references/bid-svgs/28_permission.svg +0 -31
  51. package/skills/ppt-master/references/bid-svgs/29_security.svg +0 -25
  52. package/skills/ppt-master/references/bid-svgs/30_ai_capabilities.svg +0 -21
  53. package/skills/ppt-master/references/bid-svgs/31_product_combo.svg +0 -25
  54. package/skills/ppt-master/references/bid-svgs/32_digital_transform.svg +0 -28
  55. package/skills/ppt-master/references/bid-svgs/33_chapter_cases.svg +0 -7
  56. package/skills/ppt-master/references/bid-svgs/34_cummins_case.svg +0 -23
  57. package/skills/ppt-master/references/bid-svgs/35_cpq_cost.svg +0 -22
  58. package/skills/ppt-master/references/bid-svgs/36_tech_platform.svg +0 -18
  59. package/skills/ppt-master/references/bid-svgs/37_platform_value.svg +0 -24
  60. package/skills/ppt-master/references/bid-svgs/38_operation_plan.svg +0 -25
  61. package/skills/ppt-master/references/bid-svgs/39_zpmc_case.svg +0 -21
  62. package/skills/ppt-master/references/bid-svgs/40_zpmc_apps.svg +0 -23
  63. package/skills/ppt-master/references/bid-svgs/41_chapter_service.svg +0 -7
  64. package/skills/ppt-master/references/bid-svgs/42_tech_support.svg +0 -24
  65. package/skills/ppt-master/references/bid-svgs/43_knowledge_transfer.svg +0 -25
  66. package/skills/ppt-master/references/bid-svgs/44_operation_promotion.svg +0 -20
  67. package/skills/ppt-master/references/bid-svgs/45_custom_dev_guide.svg +0 -24
  68. package/skills/ppt-master/references/bid-svgs/46_sla_guarantee.svg +0 -18
  69. package/skills/ppt-master/references/bid-svgs/47_strategic_cooperation.svg +0 -25
  70. package/skills/ppt-master/references/bid-svgs/48_ecosystem.svg +0 -24
  71. package/skills/ppt-master/references/bid-svgs/49_chapter_delivery.svg +0 -23
  72. package/skills/ppt-master/references/bid-svgs/53_pm_intro.svg +0 -24
  73. package/skills/ppt-master/references/bid-svgs/54_after_sales.svg +0 -27
  74. package/skills/ppt-master/references/bid-svgs/55_ending.svg +0 -8
  75. package/skills/ppt-master/references/company_intro.md +0 -93
  76. package/skills/ppt-master/references/company_intro_images/slide1_img00.png +0 -0
  77. package/skills/ppt-master/references/company_intro_images/slide1_img01.png +0 -0
  78. package/skills/ppt-master/references/company_intro_images/slide1_img02.png +0 -0
  79. package/skills/ppt-master/references/company_intro_images/slide1_img03.png +0 -0
  80. package/skills/ppt-master/references/company_intro_images/slide1_img04.png +0 -0
  81. package/skills/ppt-master/references/company_intro_images/slide1_img05.png +0 -0
  82. package/skills/ppt-master/references/company_intro_images/slide1_img06.png +0 -0
  83. package/skills/ppt-master/references/company_intro_images/slide1_img07.png +0 -0
  84. package/skills/ppt-master/references/company_intro_images/slide1_img08.png +0 -0
  85. package/skills/ppt-master/references/company_intro_images/slide1_img09.png +0 -0
  86. package/skills/ppt-master/references/company_intro_images/slide1_img10.png +0 -0
  87. package/skills/ppt-master/references/company_intro_images/slide1_img11.png +0 -0
  88. package/skills/ppt-master/references/company_intro_images/slide1_img12.png +0 -0
  89. package/skills/ppt-master/references/company_intro_images/slide1_img13.png +0 -0
  90. package/skills/ppt-master/references/company_intro_images/slide1_img14.png +0 -0
  91. package/skills/ppt-master/references/company_intro_images/slide1_img15.png +0 -0
  92. package/skills/ppt-master/references/company_intro_images/slide1_img16.png +0 -0
  93. package/skills/ppt-master/references/company_intro_images/slide1_img17.png +0 -0
  94. package/skills/ppt-master/references/company_intro_images/slide1_img18.png +0 -0
  95. package/skills/ppt-master/references/company_intro_images/slide1_img19.png +0 -0
  96. package/skills/ppt-master/references/company_intro_images/slide1_img20.png +0 -0
  97. package/skills/ppt-master/references/company_intro_images/slide1_img21.png +0 -0
  98. package/skills/ppt-master/references/company_intro_images/slide1_img22.png +0 -0
  99. package/skills/ppt-master/references/company_intro_images/slide1_img23.png +0 -0
  100. package/skills/ppt-master/references/company_intro_images/slide1_img24.png +0 -0
  101. package/skills/ppt-master/references/company_intro_images/slide1_img25.png +0 -0
  102. package/skills/ppt-master/references/company_intro_images/slide1_img26.png +0 -0
  103. package/skills/ppt-master/references/company_intro_images/slide1_img27.png +0 -0
  104. package/skills/ppt-master/references/company_intro_images/slide1_img28.png +0 -0
  105. package/skills/ppt-master/references/company_intro_images/slide1_img29.png +0 -0
  106. package/skills/ppt-master/references/company_intro_images/slide2_img30.png +0 -0
  107. package/skills/ppt-master/references/company_intro_images/slide2_img31.jpg +0 -0
  108. package/skills/ppt-master/references/company_intro_images/slide3_img32.png +0 -0
  109. package/skills/ppt-master/references/company_intro_images/slide3_img33.png +0 -0
  110. package/skills/ppt-master/references/drawio-integration.md +0 -144
  111. package/skills/ppt-master/requirements.txt +0 -19
  112. package/skills/ppt-master/resources/backgrounds/chapter_bg.png +0 -0
  113. package/skills/ppt-master/resources/backgrounds/company_bg.png +0 -0
  114. package/skills/ppt-master/resources/backgrounds/cover_bg.png +0 -0
  115. package/skills/ppt-master/resources/backgrounds/index.json +0 -40
  116. package/skills/ppt-master/resources/backgrounds/tech_bg.png +0 -0
  117. package/skills/ppt-master/scripts/__pycache__/config.cpython-314.pyc +0 -0
  118. package/skills/ppt-master/scripts/__pycache__/error_helper.cpython-314.pyc +0 -0
  119. package/skills/ppt-master/scripts/__pycache__/pptx_animations.cpython-314.pyc +0 -0
  120. package/skills/ppt-master/scripts/__pycache__/project_utils.cpython-314.pyc +0 -0
  121. package/skills/ppt-master/scripts/arch_diagram.py +0 -370
  122. package/skills/ppt-master/scripts/bid_init.py +0 -79
  123. package/skills/ppt-master/scripts/drawio_gen.py +0 -366
  124. package/skills/ppt-master/scripts/drawio_to_svg.py +0 -458
  125. package/skills/ppt-master/scripts/image_backends/__pycache__/__init__.cpython-314.pyc +0 -0
  126. package/skills/ppt-master/scripts/image_backends/__pycache__/backend_aigw_gemini.cpython-314.pyc +0 -0
  127. package/skills/ppt-master/scripts/image_backends/__pycache__/backend_common.cpython-314.pyc +0 -0
  128. package/skills/ppt-master/scripts/svg_finalize/__pycache__/__init__.cpython-314.pyc +0 -0
  129. package/skills/ppt-master/scripts/svg_finalize/__pycache__/crop_images.cpython-314.pyc +0 -0
  130. package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_icons.cpython-314.pyc +0 -0
  131. package/skills/ppt-master/scripts/svg_finalize/__pycache__/embed_images.cpython-314.pyc +0 -0
  132. package/skills/ppt-master/scripts/svg_finalize/__pycache__/fix_image_aspect.cpython-314.pyc +0 -0
  133. package/skills/ppt-master/scripts/svg_finalize/__pycache__/flatten_tspan.cpython-314.pyc +0 -0
  134. package/skills/ppt-master/scripts/svg_finalize/__pycache__/svg_rect_to_path.cpython-314.pyc +0 -0
  135. package/skills/ppt-master/scripts/svg_page_gen.py +0 -871
  136. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/__init__.cpython-314.pyc +0 -0
  137. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_context.cpython-314.pyc +0 -0
  138. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_converter.cpython-314.pyc +0 -0
  139. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_elements.cpython-314.pyc +0 -0
  140. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_paths.cpython-314.pyc +0 -0
  141. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_styles.cpython-314.pyc +0 -0
  142. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/drawingml_utils.cpython-314.pyc +0 -0
  143. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_builder.cpython-314.pyc +0 -0
  144. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_cli.cpython-314.pyc +0 -0
  145. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_dimensions.cpython-314.pyc +0 -0
  146. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_discovery.cpython-314.pyc +0 -0
  147. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_media.cpython-314.pyc +0 -0
  148. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_notes.cpython-314.pyc +0 -0
  149. package/skills/ppt-master/scripts/svg_to_pptx/__pycache__/pptx_slide_xml.cpython-314.pyc +0 -0
  150. /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
  151. /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
  152. /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
  153. /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
  154. /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
  155. /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
  156. /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
  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//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
  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//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
  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//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
  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/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
  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/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
  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/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
  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/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
  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/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
  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/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
  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/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
  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//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
  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//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
  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//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
  170. /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
  171. /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
  172. /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
  173. /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
  174. /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
  175. /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
  176. /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
  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//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
  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/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
  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/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
  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/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
  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/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
  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/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
  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/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
  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/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
  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//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
  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/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
  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/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
  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/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
  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/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
  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/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
  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/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
  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/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
  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//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
  194. /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
  195. /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
  196. /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
  197. /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
  198. /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
  199. /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
  200. /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
  201. /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
  202. /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
  203. /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
  204. /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
  205. /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
  206. /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
  207. /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
  208. /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
  209. /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
  210. /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
  211. /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
  212. /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
  213. /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
  214. /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
@@ -1,366 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- drawio_gen.py - Generate draw.io XML diagrams from JSON definitions.
4
-
5
- Produces .drawio files with automatic layout for architecture diagrams,
6
- flowcharts, sequence diagrams, etc.
7
-
8
- Usage:
9
- python drawio_gen.py <json_file> -o <output.drawio>
10
- python drawio_gen.py --from-stdin -o <output.drawio>
11
- echo '{"nodes":[...], "edges":[...]}' | python drawio_gen.py --from-stdin -o out.drawio
12
-
13
- JSON Schema:
14
- {
15
- "title": "System Architecture", // optional
16
- "diagram_type": "architecture", // architecture|flowchart|sequence|network
17
- "direction": "TB", // TB|LR|BT|RL (layout direction)
18
- "nodes": [
19
- {
20
- "id": "client",
21
- "label": "Client App",
22
- "group": "frontend", // optional, for grouping
23
- "shape": "rounded", // rounded|cylinder|cloud|hexagon|diamond|ellipse|rect|process|document|parallelogram
24
- "color": "#dae8fc", // fill color
25
- "stroke": "#6c8ebf", // stroke color
26
- "icon": "mxgraph.aws3.lambda", // optional mxGraph stencil
27
- "width": 140, // optional, default 120
28
- "height": 60 // optional, default 60
29
- }
30
- ],
31
- "edges": [
32
- {
33
- "source": "client",
34
- "target": "server",
35
- "label": "HTTPS", // optional
36
- "style": "dashed", // solid|dashed|dotted
37
- "arrow": "open", // open|block|classic|diamond|none
38
- "color": "#666666" // optional
39
- }
40
- ],
41
- "groups": [ // optional, for visual grouping
42
- {
43
- "id": "frontend",
44
- "label": "Frontend Layer",
45
- "color": "#f5f5f5",
46
- "stroke": "#999999"
47
- }
48
- ]
49
- }
50
- """
51
-
52
- import json
53
- import sys
54
- import argparse
55
- import hashlib
56
- import math
57
- from xml.etree.ElementTree import Element, SubElement, tostring
58
- from xml.dom.minidom import parseString
59
-
60
- # Shape style mappings
61
- SHAPE_STYLES = {
62
- "rounded": "rounded=1;whiteSpace=wrap;html=1;arcSize=12;",
63
- "rect": "whiteSpace=wrap;html=1;",
64
- "cylinder": "shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;",
65
- "cloud": "ellipse;shape=cloud;whiteSpace=wrap;html=1;",
66
- "hexagon": "shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=20;",
67
- "diamond": "rhombus;whiteSpace=wrap;html=1;",
68
- "ellipse": "ellipse;whiteSpace=wrap;html=1;",
69
- "process": "shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;size=0.1;",
70
- "document": "shape=document;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=0.25;",
71
- "parallelogram": "shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;size=20;",
72
- "database": "shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;",
73
- "server": "shape=mxgraph.cisco.servers.standard_server;whiteSpace=wrap;html=1;",
74
- "queue": "shape=mxgraph.lean_mapping.fifo_sequence_lane;whiteSpace=wrap;html=1;",
75
- "component": "shape=component;align=left;spacingLeft=36;whiteSpace=wrap;html=1;",
76
- }
77
-
78
- ARROW_STYLES = {
79
- "open": "endArrow=open;endFill=0;",
80
- "block": "endArrow=block;endFill=1;",
81
- "classic": "endArrow=classic;endFill=1;",
82
- "diamond": "endArrow=diamond;endFill=0;",
83
- "none": "endArrow=none;",
84
- }
85
-
86
- LINE_STYLES = {
87
- "solid": "",
88
- "dashed": "dashed=1;dashPattern=8 8;",
89
- "dotted": "dashed=1;dashPattern=2 2;",
90
- }
91
-
92
- DEFAULT_COLORS = [
93
- ("#dae8fc", "#6c8ebf"), # blue
94
- ("#d5e8d4", "#82b366"), # green
95
- ("#f8cecc", "#b85450"), # red
96
- ("#fff2cc", "#d6b656"), # yellow
97
- ("#e1d5e7", "#9673a6"), # purple
98
- ("#d0cee2", "#56517e"), # indigo
99
- ("#f5f5f5", "#666666"), # gray
100
- ("#ffe6cc", "#d79b00"), # orange
101
- ]
102
-
103
-
104
- def uid(text: str) -> str:
105
- return hashlib.md5(text.encode()).hexdigest()[:16]
106
-
107
-
108
- def auto_layout(nodes: list, edges: list, groups: dict, direction: str = "TB") -> dict:
109
- """Group-aware layered auto-layout. Returns {node_id: (x, y)}.
110
-
111
- Strategy:
112
- 1. Determine group ordering by inter-group edge flow (topological sort on groups)
113
- 2. Within each group, arrange nodes in a compact horizontal row
114
- 3. Groups are stacked vertically, centered on the canvas
115
- 4. Ungrouped nodes placed in their topological layer
116
- """
117
- node_map = {n["id"]: n for n in nodes}
118
- canvas_w = 1280 # target canvas width
119
-
120
- # Separate grouped and ungrouped nodes
121
- group_members = {} # group_id -> [node_ids]
122
- ungrouped = []
123
- for n in nodes:
124
- gid = n.get("group")
125
- if gid and gid in groups:
126
- group_members.setdefault(gid, []).append(n["id"])
127
- else:
128
- ungrouped.append(n["id"])
129
-
130
- # Determine group order by inter-group edge flow
131
- group_ids = list(groups.keys())
132
- group_in_deg = {gid: 0 for gid in group_ids}
133
- group_adj = {gid: set() for gid in group_ids}
134
- for e in edges:
135
- sg = node_map.get(e["source"], {}).get("group")
136
- tg = node_map.get(e["target"], {}).get("group")
137
- if sg and tg and sg != tg and sg in groups and tg in groups:
138
- if tg not in group_adj[sg]:
139
- group_adj[sg].add(tg)
140
- group_in_deg[tg] += 1
141
-
142
- # Topological sort groups
143
- group_order = []
144
- remaining_g = set(group_ids)
145
- while remaining_g:
146
- roots = [g for g in remaining_g if group_in_deg.get(g, 0) == 0]
147
- if not roots:
148
- roots = [min(remaining_g)]
149
- # Sort roots by original list order for determinism
150
- roots.sort(key=lambda g: group_ids.index(g) if g in group_ids else 999)
151
- group_order.extend(roots)
152
- for r in roots:
153
- remaining_g.discard(r)
154
- for t in group_adj.get(r, set()):
155
- group_in_deg[t] = max(0, group_in_deg[t] - 1)
156
-
157
- # Layout parameters
158
- h_gap = 30 # horizontal gap between nodes in a group
159
- v_gap = 100 # vertical gap between group rows
160
- margin_x = 60 # left margin
161
- margin_y = 40 # top margin
162
-
163
- positions = {}
164
- current_y = margin_y
165
-
166
- for gid in group_order:
167
- members = group_members.get(gid, [])
168
- if not members:
169
- continue
170
-
171
- # Calculate total row width
172
- total_w = sum(node_map[nid].get("width", 120) for nid in members) + h_gap * (len(members) - 1)
173
- # Center the row on canvas
174
- start_x = max(margin_x, (canvas_w - total_w) / 2)
175
-
176
- x = start_x
177
- max_h = 0
178
- for nid in members:
179
- n = node_map[nid]
180
- w = n.get("width", 120)
181
- h = n.get("height", 60)
182
- positions[nid] = (x, current_y)
183
- x += w + h_gap
184
- max_h = max(max_h, h)
185
-
186
- current_y += max_h + v_gap
187
-
188
- # Place ungrouped nodes
189
- if ungrouped:
190
- # Simple topological layer for ungrouped
191
- adj = {n["id"]: [] for n in nodes}
192
- in_deg = {n["id"]: 0 for n in nodes}
193
- for e in edges:
194
- s, t = e["source"], e["target"]
195
- if s in adj:
196
- adj[s].append(t)
197
- if t in in_deg:
198
- in_deg[t] = in_deg.get(t, 0) + 1
199
-
200
- for nid in ungrouped:
201
- if nid not in positions:
202
- total_w = node_map[nid].get("width", 120)
203
- start_x = (canvas_w - total_w) / 2
204
- positions[nid] = (start_x, current_y)
205
- current_y += node_map[nid].get("height", 60) + v_gap
206
-
207
- return positions
208
-
209
-
210
- def build_node_style(node: dict, color_idx: int = 0) -> str:
211
- shape = node.get("shape", "rounded")
212
- base = SHAPE_STYLES.get(shape, SHAPE_STYLES["rounded"])
213
-
214
- fill = node.get("color", DEFAULT_COLORS[color_idx % len(DEFAULT_COLORS)][0])
215
- stroke = node.get("stroke", DEFAULT_COLORS[color_idx % len(DEFAULT_COLORS)][1])
216
-
217
- style = f"{base}fillColor={fill};strokeColor={stroke};fontFamily=Helvetica;fontSize=12;"
218
-
219
- if node.get("icon"):
220
- style = f"shape={node['icon']};{style}"
221
-
222
- return style
223
-
224
-
225
- def build_edge_style(edge: dict) -> str:
226
- arrow = ARROW_STYLES.get(edge.get("arrow", "classic"), ARROW_STYLES["classic"])
227
- line = LINE_STYLES.get(edge.get("style", "solid"), "")
228
- color = edge.get("color", "#666666")
229
- return f"html=1;rounded=1;{arrow}{line}strokeColor={color};fontFamily=Helvetica;fontSize=11;"
230
-
231
-
232
- def generate_drawio(spec: dict) -> str:
233
- """Generate a .drawio XML string from a diagram specification."""
234
- nodes = spec.get("nodes", [])
235
- edges = spec.get("edges", [])
236
- groups_list = spec.get("groups", [])
237
- direction = spec.get("direction", "TB")
238
- title = spec.get("title", "Diagram")
239
-
240
- groups = {g["id"]: g for g in groups_list}
241
-
242
- # Auto layout
243
- positions = auto_layout(nodes, edges, groups, direction)
244
-
245
- # Build XML
246
- root = Element("mxfile", type="device", compressed="false")
247
- diagram = SubElement(root, "diagram", id="diagram-1", name=title)
248
- model = SubElement(diagram, "mxGraphModel", dx="1360", dy="864",
249
- grid="1", gridSize="10", guides="1", tooltips="1",
250
- connect="1", arrows="1", fold="1", page="1",
251
- pageScale="1", pageWidth="1280", pageHeight="720",
252
- math="0", shadow="0")
253
- mxroot = SubElement(model, "root")
254
- SubElement(mxroot, "mxCell", id="0")
255
- SubElement(mxroot, "mxCell", id="1", parent="0")
256
-
257
- # Group containers
258
- group_nodes = {}
259
- for g in groups_list:
260
- gid = f"group_{g['id']}"
261
- cell = SubElement(mxroot, "mxCell",
262
- id=gid, value=g.get("label", ""),
263
- style=f"rounded=1;whiteSpace=wrap;html=1;fillColor={g.get('color', '#f5f5f5')};strokeColor={g.get('stroke', '#999999')};dashed=1;dashPattern=4 4;verticalAlign=top;fontStyle=1;fontSize=13;fontFamily=Helvetica;container=1;collapsible=0;",
264
- vertex="1", parent="1")
265
- # Calculate group bounds from member nodes
266
- member_ids = [n["id"] for n in nodes if n.get("group") == g["id"]]
267
- if member_ids:
268
- xs = [positions[mid][0] for mid in member_ids if mid in positions]
269
- ys = [positions[mid][1] for mid in member_ids if mid in positions]
270
- if xs and ys:
271
- padding = 30
272
- gx = min(xs) - padding
273
- gy = min(ys) - padding - 20 # extra for label
274
- gw = max(xs) - min(xs) + 180 + 2 * padding
275
- gh = max(ys) - min(ys) + 80 + 2 * padding + 20
276
- SubElement(cell, "mxGeometry", x=str(int(gx)), y=str(int(gy)),
277
- width=str(int(gw)), height=str(int(gh)),
278
- attrib={"as": "geometry"})
279
- group_nodes[g["id"]] = gid
280
-
281
- # Nodes
282
- node_color_map = {}
283
- for idx, n in enumerate(nodes):
284
- nid = n["id"]
285
- x, y = positions.get(nid, (100, 100))
286
- w = n.get("width", 120)
287
- h = n.get("height", 60)
288
-
289
- # Assign color index by group or sequential
290
- group_id = n.get("group")
291
- if group_id:
292
- if group_id not in node_color_map:
293
- node_color_map[group_id] = len(node_color_map)
294
- cidx = node_color_map[group_id]
295
- else:
296
- cidx = idx
297
-
298
- style = build_node_style(n, cidx)
299
- parent = group_nodes.get(group_id, "1")
300
-
301
- cell = SubElement(mxroot, "mxCell",
302
- id=nid, value=n.get("label", nid),
303
- style=style, vertex="1", parent=parent)
304
-
305
- # If inside a group, use relative coordinates
306
- if group_id in group_nodes:
307
- gid = group_nodes[group_id]
308
- # Find group bounds to compute relative position
309
- member_ids = [nd["id"] for nd in nodes if nd.get("group") == group_id]
310
- gxs = [positions[mid][0] for mid in member_ids if mid in positions]
311
- gys = [positions[mid][1] for mid in member_ids if mid in positions]
312
- if gxs and gys:
313
- rel_x = x - min(gxs) + 30
314
- rel_y = y - min(gys) + 50
315
- SubElement(cell, "mxGeometry", x=str(int(rel_x)), y=str(int(rel_y)),
316
- width=str(w), height=str(h),
317
- attrib={"as": "geometry"})
318
- else:
319
- SubElement(cell, "mxGeometry", x=str(int(x)), y=str(int(y)),
320
- width=str(w), height=str(h),
321
- attrib={"as": "geometry"})
322
- else:
323
- SubElement(cell, "mxGeometry", x=str(int(x)), y=str(int(y)),
324
- width=str(w), height=str(h),
325
- attrib={"as": "geometry"})
326
-
327
- # Edges
328
- for e in edges:
329
- eid = uid(f"{e['source']}-{e['target']}-{e.get('label','')}")
330
- style = build_edge_style(e)
331
- cell = SubElement(mxroot, "mxCell",
332
- id=eid, value=e.get("label", ""),
333
- style=style, edge="1", parent="1",
334
- source=e["source"], target=e["target"])
335
- SubElement(cell, "mxGeometry", relative="1",
336
- attrib={"as": "geometry"})
337
-
338
- # Pretty print
339
- xml_str = tostring(root, encoding="unicode")
340
- return parseString(xml_str).toprettyxml(indent=" ", encoding=None)
341
-
342
-
343
- def main():
344
- parser = argparse.ArgumentParser(description="Generate draw.io diagrams from JSON")
345
- parser.add_argument("input", nargs="?", help="JSON input file")
346
- parser.add_argument("--from-stdin", action="store_true", help="Read JSON from stdin")
347
- parser.add_argument("-o", "--output", required=True, help="Output .drawio file")
348
- args = parser.parse_args()
349
-
350
- if args.from_stdin:
351
- spec = json.load(sys.stdin)
352
- elif args.input:
353
- with open(args.input, "r", encoding="utf-8") as f:
354
- spec = json.load(f)
355
- else:
356
- parser.error("Provide an input file or --from-stdin")
357
-
358
- xml = generate_drawio(spec)
359
- with open(args.output, "w", encoding="utf-8") as f:
360
- f.write(xml)
361
- print(f"✅ Generated: {args.output}")
362
- print(f" Nodes: {len(spec.get('nodes', []))}, Edges: {len(spec.get('edges', []))}")
363
-
364
-
365
- if __name__ == "__main__":
366
- main()