@bovinphang/frontend-craft 2.7.0 → 2.8.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 (380) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +34 -0
  4. package/CHANGELOG.zh-CN.md +34 -0
  5. package/README.md +1 -1
  6. package/README.openclaw.md +99 -43
  7. package/README.openclaw.zh-CN.md +99 -43
  8. package/README.zh-CN.md +1 -1
  9. package/agents/fec-architect.md +70 -70
  10. package/agents/fec-code-reviewer.md +82 -82
  11. package/agents/fec-debugger.md +20 -20
  12. package/agents/fec-design-token-mapper.md +36 -36
  13. package/agents/fec-doc-updater.md +13 -13
  14. package/agents/fec-e2e-runner.md +45 -45
  15. package/agents/fec-figma-implementer.md +59 -59
  16. package/agents/fec-performance-optimizer.md +128 -128
  17. package/agents/fec-refactor-cleaner.md +14 -14
  18. package/agents/fec-security-reviewer.md +66 -67
  19. package/agents/fec-test-planner.md +27 -27
  20. package/agents/fec-typescript-reviewer.md +87 -87
  21. package/agents/fec-ui-checker.md +74 -74
  22. package/commands/fec-debug.md +19 -19
  23. package/commands/fec-doc-sync.md +11 -11
  24. package/commands/fec-init.md +37 -38
  25. package/commands/fec-plan.md +58 -58
  26. package/commands/fec-refactor-clean.md +11 -11
  27. package/commands/fec-review.md +41 -41
  28. package/commands/fec-scaffold.md +41 -41
  29. package/commands/fec-tdd.md +13 -13
  30. package/dist/bin/frontend-craft.js +29 -27
  31. package/docs/example-prompts.md +3 -0
  32. package/docs/ja-JP/README.md +1 -1
  33. package/docs/ko-KR/README.md +1 -1
  34. package/docs/project-structure.md +13 -5
  35. package/docs/zh-CN/example-prompts.md +3 -0
  36. package/docs/zh-CN/project-structure.md +6 -1
  37. package/docs/zh-TW/README.md +1 -1
  38. package/localized/zh-CN/agents/fec-architect.md +125 -0
  39. package/localized/zh-CN/agents/fec-code-reviewer.md +152 -0
  40. package/localized/zh-CN/agents/fec-debugger.md +44 -0
  41. package/localized/zh-CN/agents/fec-design-token-mapper.md +75 -0
  42. package/localized/zh-CN/agents/fec-doc-updater.md +30 -0
  43. package/localized/zh-CN/agents/fec-e2e-runner.md +107 -0
  44. package/localized/zh-CN/agents/fec-figma-implementer.md +104 -0
  45. package/localized/zh-CN/agents/fec-performance-optimizer.md +293 -0
  46. package/localized/zh-CN/agents/fec-refactor-cleaner.md +32 -0
  47. package/localized/zh-CN/agents/fec-security-reviewer.md +116 -0
  48. package/localized/zh-CN/agents/fec-test-planner.md +50 -0
  49. package/localized/zh-CN/agents/fec-typescript-reviewer.md +142 -0
  50. package/localized/zh-CN/agents/fec-ui-checker.md +120 -0
  51. package/localized/zh-CN/commands/fec-debug.md +30 -0
  52. package/localized/zh-CN/commands/fec-doc-sync.md +19 -0
  53. package/localized/zh-CN/commands/fec-init.md +70 -0
  54. package/localized/zh-CN/commands/fec-plan.md +94 -0
  55. package/localized/zh-CN/commands/fec-refactor-clean.md +19 -0
  56. package/localized/zh-CN/commands/fec-review.md +66 -0
  57. package/localized/zh-CN/commands/fec-scaffold.md +205 -0
  58. package/localized/zh-CN/commands/fec-tdd.md +21 -0
  59. package/localized/zh-CN/skills/TEMPLATE.md +155 -0
  60. package/localized/zh-CN/skills/eval_queries.json +1013 -0
  61. package/localized/zh-CN/skills/fec-accessibility-check/SKILL.md +39 -0
  62. package/localized/zh-CN/skills/fec-accessibility-check/references/report-template.md +23 -0
  63. package/localized/zh-CN/skills/fec-accessibility-check/references/screen-reader-testing.md +33 -0
  64. package/localized/zh-CN/skills/fec-alchemy/SKILL.md +74 -0
  65. package/localized/zh-CN/skills/fec-alchemy/assets/absorption-plan-template.md +47 -0
  66. package/localized/zh-CN/skills/fec-alchemy/assets/intake-template.md +55 -0
  67. package/localized/zh-CN/skills/fec-alchemy/assets/review-checklist.md +31 -0
  68. package/localized/zh-CN/skills/fec-alchemy/references/methodology.md +94 -0
  69. package/localized/zh-CN/skills/fec-alchemy/references/originality-and-licensing.md +57 -0
  70. package/localized/zh-CN/skills/fec-api-integration/SKILL.md +78 -0
  71. package/localized/zh-CN/skills/fec-api-integration/references/integration-patterns.md +80 -0
  72. package/localized/zh-CN/skills/fec-backend-requirements-handoff/SKILL.md +45 -0
  73. package/localized/zh-CN/skills/fec-browser-storage/SKILL.md +34 -0
  74. package/localized/zh-CN/skills/fec-browser-storage/references/storage-patterns.md +65 -0
  75. package/localized/zh-CN/skills/fec-canvas-threejs/SKILL.md +66 -0
  76. package/localized/zh-CN/skills/fec-canvas-threejs/references/rendering-patterns.md +67 -0
  77. package/localized/zh-CN/skills/fec-canvas-threejs/references/shader-webgl-patterns.md +67 -0
  78. package/localized/zh-CN/skills/fec-code-review/SKILL.md +143 -0
  79. package/localized/zh-CN/skills/fec-code-review/references/report-template.md +29 -0
  80. package/localized/zh-CN/skills/fec-component-testing/SKILL.md +119 -0
  81. package/localized/zh-CN/skills/fec-data-fetching/SKILL.md +62 -0
  82. package/localized/zh-CN/skills/fec-data-fetching/references/query-patterns.md +103 -0
  83. package/localized/zh-CN/skills/fec-debug-framework/SKILL.md +157 -0
  84. package/localized/zh-CN/skills/fec-debug-framework/references/report-template.md +58 -0
  85. package/localized/zh-CN/skills/fec-dependency-upgrade/SKILL.md +34 -0
  86. package/localized/zh-CN/skills/fec-dependency-upgrade/references/dependency-upgrade-workflow.md +56 -0
  87. package/localized/zh-CN/skills/fec-doc-sync/SKILL.md +39 -0
  88. package/localized/zh-CN/skills/fec-drawio-studio/SKILL.md +73 -0
  89. package/localized/zh-CN/skills/fec-drawio-studio/data/THIRD_PARTY_NOTICES.md +10 -0
  90. package/localized/zh-CN/skills/fec-drawio-studio/data/brand-icons.json +878 -0
  91. package/localized/zh-CN/skills/fec-drawio-studio/data/shape-index.json +83570 -0
  92. package/localized/zh-CN/skills/fec-drawio-studio/references/data-residency.md +27 -0
  93. package/localized/zh-CN/skills/fec-drawio-studio/references/diagram-patterns.md +60 -0
  94. package/localized/zh-CN/skills/fec-drawio-studio/references/flowchart-quality.md +49 -0
  95. package/localized/zh-CN/skills/fec-drawio-studio/references/layout-and-export.md +72 -0
  96. package/localized/zh-CN/skills/fec-drawio-studio/references/troubleshooting.md +29 -0
  97. package/localized/zh-CN/skills/fec-drawio-studio/references/xml-and-mermaid.md +58 -0
  98. package/localized/zh-CN/skills/fec-drawio-studio/scripts/brand-symbols.mjs +99 -0
  99. package/localized/zh-CN/skills/fec-drawio-studio/scripts/diagram-lint.mjs +205 -0
  100. package/localized/zh-CN/skills/fec-drawio-studio/scripts/diagram-url.mjs +102 -0
  101. package/localized/zh-CN/skills/fec-drawio-studio/scripts/drawio-export.mjs +134 -0
  102. package/localized/zh-CN/skills/fec-drawio-studio/scripts/layout-graph.mjs +107 -0
  103. package/localized/zh-CN/skills/fec-drawio-studio/scripts/png-embed-fix.mjs +26 -0
  104. package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-go-packages.mjs +36 -0
  105. package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-js-modules.mjs +52 -0
  106. package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-python-classes.mjs +30 -0
  107. package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-python-modules.mjs +55 -0
  108. package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-rust-modules.mjs +35 -0
  109. package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-ts-modules.mjs +7 -0
  110. package/localized/zh-CN/skills/fec-drawio-studio/scripts/shape-query.mjs +121 -0
  111. package/localized/zh-CN/skills/fec-drawio-studio/scripts/studio-core.mjs +139 -0
  112. package/localized/zh-CN/skills/fec-drawio-studio/styles/built-in/corporate.json +49 -0
  113. package/localized/zh-CN/skills/fec-drawio-studio/styles/built-in/default.json +49 -0
  114. package/localized/zh-CN/skills/fec-drawio-studio/styles/built-in/handdrawn.json +49 -0
  115. package/localized/zh-CN/skills/fec-drawio-studio/styles/schema.json +112 -0
  116. package/localized/zh-CN/skills/fec-e2e-testing/SKILL.md +42 -0
  117. package/localized/zh-CN/skills/fec-e2e-testing/references/e2e-ci-reporting.md +62 -0
  118. package/localized/zh-CN/skills/fec-e2e-testing/references/e2e-special-scenarios.md +52 -0
  119. package/localized/zh-CN/skills/fec-e2e-testing/references/e2e-visual-regression.md +60 -0
  120. package/localized/zh-CN/skills/fec-e2e-testing/references/playwright-patterns.md +95 -0
  121. package/localized/zh-CN/skills/fec-form-handling/SKILL.md +76 -0
  122. package/localized/zh-CN/skills/fec-form-handling/references/advanced-form-patterns.md +101 -0
  123. package/localized/zh-CN/skills/fec-image-generation/SKILL.md +80 -0
  124. package/localized/zh-CN/skills/fec-image-generation/assets/interactive-diagram.html +371 -0
  125. package/localized/zh-CN/skills/fec-image-generation/references/artifact-routing.md +80 -0
  126. package/localized/zh-CN/skills/fec-image-generation/references/diagram-workflows.md +74 -0
  127. package/localized/zh-CN/skills/fec-image-generation/references/html-technical-diagrams.md +236 -0
  128. package/localized/zh-CN/skills/fec-image-generation/references/png-qa-autofix.md +30 -0
  129. package/localized/zh-CN/skills/fec-image-generation/scripts/export-diagram.mjs +364 -0
  130. package/localized/zh-CN/skills/fec-image-generation/scripts/interactive-diagram-server.mjs +654 -0
  131. package/localized/zh-CN/skills/fec-image-generation/scripts/png-qa.mjs +431 -0
  132. package/localized/zh-CN/skills/fec-image-generation/scripts/tech-diagram-render.mjs +1397 -0
  133. package/localized/zh-CN/skills/fec-implement-from-design/SKILL.md +129 -0
  134. package/localized/zh-CN/skills/fec-implement-from-design/references/design-plan-template.md +36 -0
  135. package/localized/zh-CN/skills/fec-legacy-to-modern-migration/SKILL.md +46 -0
  136. package/localized/zh-CN/skills/fec-legacy-to-modern-migration/references/migration-execution-checklist.md +110 -0
  137. package/localized/zh-CN/skills/fec-legacy-to-modern-migration/references/migration-report-template.md +41 -0
  138. package/localized/zh-CN/skills/fec-legacy-to-modern-migration/references/migration-strategy-and-mapping.md +48 -0
  139. package/localized/zh-CN/skills/fec-legacy-web-standard/SKILL.md +35 -0
  140. package/localized/zh-CN/skills/fec-legacy-web-standard/references/legacy-patterns.md +85 -0
  141. package/localized/zh-CN/skills/fec-list-virtualization/SKILL.md +34 -0
  142. package/localized/zh-CN/skills/fec-list-virtualization/references/virtualization-patterns.md +80 -0
  143. package/localized/zh-CN/skills/fec-monorepo-project-standard/SKILL.md +142 -0
  144. package/localized/zh-CN/skills/fec-motion-interaction/SKILL.md +73 -0
  145. package/localized/zh-CN/skills/fec-motion-interaction/references/motion-patterns.md +112 -0
  146. package/localized/zh-CN/skills/fec-nextjs-project-standard/SKILL.md +123 -0
  147. package/localized/zh-CN/skills/fec-nuxt-project-standard/SKILL.md +122 -0
  148. package/localized/zh-CN/skills/fec-performance-optimization/SKILL.md +80 -0
  149. package/localized/zh-CN/skills/fec-performance-optimization/references/framework-performance-patterns.md +38 -0
  150. package/localized/zh-CN/skills/fec-performance-optimization/references/report-template.md +59 -0
  151. package/localized/zh-CN/skills/fec-pwa-implementation/SKILL.md +35 -0
  152. package/localized/zh-CN/skills/fec-pwa-implementation/references/manifest-and-icons.md +53 -0
  153. package/localized/zh-CN/skills/fec-pwa-implementation/references/service-worker-workbox.md +68 -0
  154. package/localized/zh-CN/skills/fec-react-project-standard/SKILL.md +91 -0
  155. package/localized/zh-CN/skills/fec-react-project-standard/references/react-performance-patterns.md +35 -0
  156. package/localized/zh-CN/skills/fec-react-project-standard/references/react-project-structure.md +197 -0
  157. package/localized/zh-CN/skills/fec-react-project-standard/references/react-quality-patterns.md +131 -0
  158. package/localized/zh-CN/skills/fec-react-project-standard/references/react-runtime-patterns.md +293 -0
  159. package/localized/zh-CN/skills/fec-refactor-clean/SKILL.md +51 -0
  160. package/localized/zh-CN/skills/fec-refactor-clean/references/report-template.md +42 -0
  161. package/localized/zh-CN/skills/fec-responsive-layout/SKILL.md +34 -0
  162. package/localized/zh-CN/skills/fec-responsive-layout/references/responsive-layout-patterns.md +70 -0
  163. package/localized/zh-CN/skills/fec-route-protection/SKILL.md +135 -0
  164. package/localized/zh-CN/skills/fec-security-review/SKILL.md +38 -0
  165. package/localized/zh-CN/skills/fec-security-review/references/report-template.md +27 -0
  166. package/localized/zh-CN/skills/fec-security-review/references/security-checklist.md +64 -0
  167. package/localized/zh-CN/skills/fec-source-driven-development/SKILL.md +87 -0
  168. package/localized/zh-CN/skills/fec-state-management/SKILL.md +140 -0
  169. package/localized/zh-CN/skills/fec-state-management/references/state-patterns.md +109 -0
  170. package/localized/zh-CN/skills/fec-storybook-component-doc/SKILL.md +37 -0
  171. package/localized/zh-CN/skills/fec-storybook-component-doc/references/story-patterns.md +118 -0
  172. package/localized/zh-CN/skills/fec-svg-animation/SKILL.md +148 -0
  173. package/localized/zh-CN/skills/fec-tailwind-design-system/SKILL.md +34 -0
  174. package/localized/zh-CN/skills/fec-tailwind-design-system/references/tailwind-system-patterns.md +59 -0
  175. package/localized/zh-CN/skills/fec-tdd-workflow/SKILL.md +52 -0
  176. package/localized/zh-CN/skills/fec-testing-strategy/SKILL.md +45 -0
  177. package/localized/zh-CN/skills/fec-typescript-project-standard/SKILL.md +54 -0
  178. package/localized/zh-CN/skills/fec-typescript-project-standard/references/type-safety-patterns.md +102 -0
  179. package/localized/zh-CN/skills/fec-typescript-project-standard/references/type-safety.md +148 -0
  180. package/localized/zh-CN/skills/fec-ui-design/SKILL.md +108 -0
  181. package/localized/zh-CN/skills/fec-ui-design/data/product-rules.json +231 -0
  182. package/localized/zh-CN/skills/fec-ui-design/data/stack-ui-rules.json +146 -0
  183. package/localized/zh-CN/skills/fec-ui-design/data/style-archetypes.json +373 -0
  184. package/localized/zh-CN/skills/fec-ui-design/data/ux-quality-rules.json +203 -0
  185. package/localized/zh-CN/skills/fec-ui-design/references/design-intelligence.md +97 -0
  186. package/localized/zh-CN/skills/fec-ui-design/references/master-page-overrides.md +30 -0
  187. package/localized/zh-CN/skills/fec-ui-design/references/pre-delivery-checklist.md +39 -0
  188. package/localized/zh-CN/skills/fec-ui-design/scripts/design-system.mjs +648 -0
  189. package/localized/zh-CN/skills/fec-validation-fix/SKILL.md +51 -0
  190. package/localized/zh-CN/skills/fec-validation-fix/references/report-template.md +43 -0
  191. package/localized/zh-CN/skills/fec-vite-project-standard/SKILL.md +83 -0
  192. package/localized/zh-CN/skills/fec-vue3-project-standard/SKILL.md +58 -0
  193. package/localized/zh-CN/skills/fec-vue3-project-standard/references/vue3-composables-routing.md +162 -0
  194. package/localized/zh-CN/skills/fec-vue3-project-standard/references/vue3-performance-patterns.md +13 -0
  195. package/localized/zh-CN/skills/fec-vue3-project-standard/references/vue3-project-structure.md +176 -0
  196. package/localized/zh-CN/skills/fec-vue3-project-standard/references/vue3-state-api-quality.md +216 -0
  197. package/localized/zh-CN/skills/fec-web-video-presentation/SKILL.md +61 -0
  198. package/localized/zh-CN/skills/fec-web-video-presentation/data/starter-themes.json +59 -0
  199. package/localized/zh-CN/skills/fec-web-video-presentation/references/chapter-craft.md +37 -0
  200. package/localized/zh-CN/skills/fec-web-video-presentation/references/content-plan.md +38 -0
  201. package/localized/zh-CN/skills/fec-web-video-presentation/references/recording-and-audio.md +33 -0
  202. package/localized/zh-CN/skills/fec-web-video-presentation/references/theme-system.md +36 -0
  203. package/localized/zh-CN/skills/fec-web-video-presentation/scripts/create-video-presentation.mjs +430 -0
  204. package/localized/zh-CN/skills/fec-web-workers/SKILL.md +35 -0
  205. package/localized/zh-CN/skills/fec-web-workers/references/advanced-workers.md +54 -0
  206. package/localized/zh-CN/skills/fec-web-workers/references/basic-worker.md +67 -0
  207. package/localized/zh-CN/skills/metadata.json +1646 -0
  208. package/localized/zh-CN/skills/relations.json +755 -0
  209. package/localized/zh-CN/templates/claude/CLAUDE.md +106 -0
  210. package/localized/zh-CN/templates/claude/settings.json +62 -0
  211. package/localized/zh-CN/templates/codex/AGENTS.md +105 -0
  212. package/localized/zh-CN/templates/codex/config.toml +32 -0
  213. package/localized/zh-CN/templates/openclaw/AGENTS.md +101 -0
  214. package/localized/zh-CN/templates/openclaw/OPENCLAW-CONFIG.md +12 -0
  215. package/localized/zh-CN/templates/shared/rules/fec-agent-workflow.md +54 -0
  216. package/localized/zh-CN/templates/shared/rules/fec-api-layer.md +99 -0
  217. package/localized/zh-CN/templates/shared/rules/fec-ci-cd.md +40 -0
  218. package/localized/zh-CN/templates/shared/rules/fec-code-comments.md +33 -0
  219. package/localized/zh-CN/templates/shared/rules/fec-design-system.md +72 -0
  220. package/localized/zh-CN/templates/shared/rules/fec-error-handling.md +56 -0
  221. package/localized/zh-CN/templates/shared/rules/fec-git-conventions.md +73 -0
  222. package/localized/zh-CN/templates/shared/rules/fec-i18n.md +64 -0
  223. package/localized/zh-CN/templates/shared/rules/fec-naming-conventions.md +120 -0
  224. package/localized/zh-CN/templates/shared/rules/fec-performance.md +101 -0
  225. package/localized/zh-CN/templates/shared/rules/fec-react.md +82 -0
  226. package/localized/zh-CN/templates/shared/rules/fec-refactoring.md +47 -0
  227. package/localized/zh-CN/templates/shared/rules/fec-rendering-patterns.md +40 -0
  228. package/localized/zh-CN/templates/shared/rules/fec-responsive-design.md +50 -0
  229. package/localized/zh-CN/templates/shared/rules/fec-source-driven-development.md +31 -0
  230. package/localized/zh-CN/templates/shared/rules/fec-state-management.md +60 -0
  231. package/localized/zh-CN/templates/shared/rules/fec-testing.md +98 -0
  232. package/localized/zh-CN/templates/shared/rules/fec-typescript.md +112 -0
  233. package/localized/zh-CN/templates/shared/rules/fec-vue.md +64 -0
  234. package/localized/zh-CN/templates/shared/rules/fec-working-modes.md +50 -0
  235. package/openclaw.plugin.json +1 -1
  236. package/package.json +3 -2
  237. package/skills/TEMPLATE.md +74 -74
  238. package/skills/eval_queries.json +678 -678
  239. package/skills/fec-accessibility-check/SKILL.md +21 -21
  240. package/skills/fec-accessibility-check/references/report-template.md +12 -12
  241. package/skills/fec-accessibility-check/references/screen-reader-testing.md +24 -24
  242. package/skills/fec-alchemy/SKILL.md +50 -50
  243. package/skills/fec-alchemy/assets/absorption-plan-template.md +32 -32
  244. package/skills/fec-alchemy/assets/intake-template.md +55 -55
  245. package/skills/fec-alchemy/assets/review-checklist.md +23 -23
  246. package/skills/fec-alchemy/references/methodology.md +66 -66
  247. package/skills/fec-alchemy/references/originality-and-licensing.md +42 -42
  248. package/skills/fec-api-integration/SKILL.md +61 -61
  249. package/skills/fec-api-integration/references/integration-patterns.md +30 -30
  250. package/skills/fec-backend-requirements-handoff/SKILL.md +25 -25
  251. package/skills/fec-browser-storage/SKILL.md +16 -16
  252. package/skills/fec-browser-storage/references/storage-patterns.md +16 -16
  253. package/skills/fec-canvas-threejs/SKILL.md +21 -21
  254. package/skills/fec-canvas-threejs/references/rendering-patterns.md +10 -10
  255. package/skills/fec-canvas-threejs/references/shader-webgl-patterns.md +37 -37
  256. package/skills/fec-code-review/SKILL.md +94 -94
  257. package/skills/fec-code-review/references/report-template.md +13 -13
  258. package/skills/fec-component-testing/SKILL.md +39 -39
  259. package/skills/fec-data-fetching/SKILL.md +16 -16
  260. package/skills/fec-data-fetching/references/query-patterns.md +27 -27
  261. package/skills/fec-debug-framework/SKILL.md +95 -95
  262. package/skills/fec-debug-framework/references/report-template.md +34 -34
  263. package/skills/fec-dependency-upgrade/SKILL.md +17 -17
  264. package/skills/fec-dependency-upgrade/references/dependency-upgrade-workflow.md +31 -31
  265. package/skills/fec-doc-sync/SKILL.md +23 -23
  266. package/skills/fec-drawio-studio/SKILL.md +42 -38
  267. package/skills/fec-drawio-studio/data/THIRD_PARTY_NOTICES.md +1 -1
  268. package/skills/fec-drawio-studio/data/shape-index.json +83570 -0
  269. package/skills/fec-drawio-studio/references/diagram-patterns.md +19 -0
  270. package/skills/fec-drawio-studio/references/flowchart-quality.md +49 -0
  271. package/skills/fec-drawio-studio/references/layout-and-export.md +18 -3
  272. package/skills/fec-drawio-studio/references/xml-and-mermaid.md +5 -1
  273. package/skills/fec-drawio-studio/scripts/diagram-lint.mjs +62 -0
  274. package/skills/fec-drawio-studio/scripts/drawio-export.mjs +134 -0
  275. package/skills/fec-drawio-studio/scripts/shape-query.mjs +55 -15
  276. package/skills/fec-e2e-testing/SKILL.md +24 -24
  277. package/skills/fec-e2e-testing/references/e2e-ci-reporting.md +20 -20
  278. package/skills/fec-e2e-testing/references/e2e-special-scenarios.md +10 -10
  279. package/skills/fec-e2e-testing/references/e2e-visual-regression.md +17 -17
  280. package/skills/fec-e2e-testing/references/playwright-patterns.md +6 -6
  281. package/skills/fec-form-handling/SKILL.md +21 -21
  282. package/skills/fec-form-handling/references/advanced-form-patterns.md +41 -41
  283. package/skills/fec-image-generation/SKILL.md +54 -29
  284. package/skills/fec-image-generation/assets/interactive-diagram.html +371 -0
  285. package/skills/fec-image-generation/references/diagram-workflows.md +33 -2
  286. package/skills/fec-image-generation/references/html-technical-diagrams.md +236 -0
  287. package/skills/fec-image-generation/scripts/export-diagram.mjs +364 -0
  288. package/skills/fec-image-generation/scripts/interactive-diagram-server.mjs +654 -0
  289. package/skills/fec-image-generation/scripts/tech-diagram-render.mjs +1397 -0
  290. package/skills/fec-implement-from-design/SKILL.md +81 -81
  291. package/skills/fec-implement-from-design/references/design-plan-template.md +16 -16
  292. package/skills/fec-legacy-to-modern-migration/SKILL.md +29 -29
  293. package/skills/fec-legacy-to-modern-migration/references/migration-execution-checklist.md +81 -81
  294. package/skills/fec-legacy-to-modern-migration/references/migration-report-template.md +37 -37
  295. package/skills/fec-legacy-to-modern-migration/references/migration-strategy-and-mapping.md +31 -31
  296. package/skills/fec-legacy-web-standard/SKILL.md +17 -17
  297. package/skills/fec-legacy-web-standard/references/legacy-patterns.md +16 -16
  298. package/skills/fec-list-virtualization/SKILL.md +16 -16
  299. package/skills/fec-list-virtualization/references/virtualization-patterns.md +31 -31
  300. package/skills/fec-monorepo-project-standard/SKILL.md +52 -52
  301. package/skills/fec-motion-interaction/SKILL.md +51 -51
  302. package/skills/fec-motion-interaction/references/motion-patterns.md +11 -11
  303. package/skills/fec-nextjs-project-standard/SKILL.md +64 -64
  304. package/skills/fec-nuxt-project-standard/SKILL.md +57 -57
  305. package/skills/fec-performance-optimization/SKILL.md +54 -54
  306. package/skills/fec-performance-optimization/references/framework-performance-patterns.md +23 -23
  307. package/skills/fec-performance-optimization/references/report-template.md +31 -31
  308. package/skills/fec-pwa-implementation/SKILL.md +17 -17
  309. package/skills/fec-pwa-implementation/references/manifest-and-icons.md +12 -12
  310. package/skills/fec-pwa-implementation/references/service-worker-workbox.md +13 -13
  311. package/skills/fec-react-project-standard/SKILL.md +72 -72
  312. package/skills/fec-react-project-standard/references/react-performance-patterns.md +28 -28
  313. package/skills/fec-react-project-standard/references/react-project-structure.md +112 -112
  314. package/skills/fec-react-project-standard/references/react-quality-patterns.md +72 -72
  315. package/skills/fec-react-project-standard/references/react-runtime-patterns.md +94 -94
  316. package/skills/fec-refactor-clean/SKILL.md +30 -30
  317. package/skills/fec-refactor-clean/references/report-template.md +23 -23
  318. package/skills/fec-responsive-layout/SKILL.md +17 -17
  319. package/skills/fec-responsive-layout/references/responsive-layout-patterns.md +37 -37
  320. package/skills/fec-route-protection/SKILL.md +26 -26
  321. package/skills/fec-security-review/SKILL.md +20 -20
  322. package/skills/fec-security-review/references/report-template.md +12 -12
  323. package/skills/fec-security-review/references/security-checklist.md +27 -27
  324. package/skills/fec-source-driven-development/SKILL.md +59 -59
  325. package/skills/fec-state-management/SKILL.md +34 -34
  326. package/skills/fec-state-management/references/state-patterns.md +19 -19
  327. package/skills/fec-storybook-component-doc/SKILL.md +19 -19
  328. package/skills/fec-storybook-component-doc/references/story-patterns.md +12 -12
  329. package/skills/fec-svg-animation/SKILL.md +32 -32
  330. package/skills/fec-tailwind-design-system/SKILL.md +17 -17
  331. package/skills/fec-tailwind-design-system/references/tailwind-system-patterns.md +36 -36
  332. package/skills/fec-tdd-workflow/SKILL.md +28 -28
  333. package/skills/fec-testing-strategy/SKILL.md +29 -29
  334. package/skills/fec-typescript-project-standard/SKILL.md +38 -38
  335. package/skills/fec-typescript-project-standard/references/type-safety-patterns.md +20 -20
  336. package/skills/fec-typescript-project-standard/references/type-safety.md +18 -18
  337. package/skills/fec-ui-design/SKILL.md +90 -90
  338. package/skills/fec-ui-design/references/design-intelligence.md +61 -61
  339. package/skills/fec-ui-design/references/master-page-overrides.md +15 -15
  340. package/skills/fec-ui-design/references/pre-delivery-checklist.md +38 -38
  341. package/skills/fec-validation-fix/SKILL.md +26 -26
  342. package/skills/fec-validation-fix/references/report-template.md +25 -25
  343. package/skills/fec-vite-project-standard/SKILL.md +39 -39
  344. package/skills/fec-vue3-project-standard/SKILL.md +38 -38
  345. package/skills/fec-vue3-project-standard/references/vue3-composables-routing.md +36 -36
  346. package/skills/fec-vue3-project-standard/references/vue3-performance-patterns.md +8 -8
  347. package/skills/fec-vue3-project-standard/references/vue3-project-structure.md +112 -112
  348. package/skills/fec-vue3-project-standard/references/vue3-state-api-quality.md +74 -74
  349. package/skills/fec-web-video-presentation/SKILL.md +33 -33
  350. package/skills/fec-web-workers/SKILL.md +16 -16
  351. package/skills/fec-web-workers/references/advanced-workers.md +13 -13
  352. package/skills/fec-web-workers/references/basic-worker.md +8 -8
  353. package/skills/metadata.json +121 -115
  354. package/skills/relations.json +4 -0
  355. package/templates/claude/CLAUDE.md +60 -60
  356. package/templates/codex/AGENTS.md +76 -76
  357. package/templates/codex/config.toml +4 -4
  358. package/templates/openclaw/AGENTS.md +68 -68
  359. package/templates/openclaw/OPENCLAW-CONFIG.md +8 -8
  360. package/templates/shared/rules/fec-agent-workflow.md +40 -40
  361. package/templates/shared/rules/fec-api-layer.md +52 -52
  362. package/templates/shared/rules/fec-ci-cd.md +29 -29
  363. package/templates/shared/rules/fec-code-comments.md +22 -22
  364. package/templates/shared/rules/fec-design-system.md +53 -53
  365. package/templates/shared/rules/fec-error-handling.md +40 -40
  366. package/templates/shared/rules/fec-git-conventions.md +42 -42
  367. package/templates/shared/rules/fec-i18n.md +48 -48
  368. package/templates/shared/rules/fec-naming-conventions.md +91 -91
  369. package/templates/shared/rules/fec-performance.md +78 -78
  370. package/templates/shared/rules/fec-react.md +58 -58
  371. package/templates/shared/rules/fec-refactoring.md +34 -34
  372. package/templates/shared/rules/fec-rendering-patterns.md +36 -36
  373. package/templates/shared/rules/fec-responsive-design.md +37 -37
  374. package/templates/shared/rules/fec-source-driven-development.md +22 -22
  375. package/templates/shared/rules/fec-state-management.md +56 -56
  376. package/templates/shared/rules/fec-testing.md +64 -64
  377. package/templates/shared/rules/fec-typescript.md +75 -75
  378. package/templates/shared/rules/fec-vue.md +42 -42
  379. package/templates/shared/rules/fec-working-modes.md +34 -34
  380. package/skills/fec-drawio-studio/data/shape-index.json.gz +0 -0
@@ -0,0 +1,236 @@
1
+ # HTML 技术图
2
+
3
+ 当技术图需要单文件浏览器打开、便于分享、支持暗/亮主题,并且导出 PNG 后要做视觉 QA 时,使用这一路线。
4
+
5
+ 这一路线补充但不替代其他图表源:
6
+
7
+ | 需求 | 优先选择 |
8
+ | ---- | -------- |
9
+ | 小型 Markdown 维护图 | Mermaid、Graphviz 或 SVG |
10
+ | 后续人工编辑的图源 | `fec-drawio-studio` 和 `.drawio` |
11
+ | 浏览器可打开的主题化技术图 | HTML 技术图路线 |
12
+ | 位图优先的视觉概念、海报、产品图或图片编辑 | 图片生成或编辑路线 |
13
+
14
+ ## 支持的图表意图
15
+
16
+ - `architecture`:系统拓扑、系统蓝图、部署拓扑、云区域、信任边界、客户端、网关、服务、数据存储、事件总线、认证流、Agent runtime 图、memory/recall 总览、before/after 架构对比和基础设施总览。
17
+ - `workflow`:职责泳道、流程地图、审批门禁、自动化运行、异常路径、循环流程、runbook、CI/CD、事故响应、工具调用和请求生命周期。
18
+ - `sequence`:参与者随时间交互、API 调用链、缓存回退、鉴权检查、异步链路和返回消息。
19
+ - `dataflow`:来源、采集、处理、存储、消费者、PII 边界、治理、分析和血缘。
20
+ - `lifecycle`:对象状态、终止状态、重试、等待、取消、超时、部署或订单状态流转。
21
+
22
+ 浏览器可交付的架构总览优先用 `architecture` 模式。需要 `.drawio` 源、官方厂商图标、diagrams.net 手工编辑或复杂自动布局时,改用 `fec-drawio-studio`。
23
+
24
+ ## 主题化语义图
25
+
26
+ 同一份 JSON 源需要更明确的交付语气时,可以使用 `visual.style`:`default`、`terminal`、`blueprint`、`minimal`、`glass`、`warm`、`openai` 或 `editorial-dark`。
27
+
28
+ Agent、memory 和 AI 工作流图优先在 architecture 节点上使用语义 `type`:
29
+
30
+ - 参与者和入口:`user`、`browser`、`gateway`。
31
+ - 智能与编排:`agent`、`model`、`tool`。
32
+ - 记忆与知识:`memory`、`vectorstore`、`graphdb`、`document`。
33
+ - 运行时流动:`queue`、`messagebus`、`backend`、`external`。
34
+
35
+ 连线不仅表达方向,还需要表达含义时使用 `flow`:
36
+
37
+ - `control`:编排、策略、触发或命令。
38
+ - `data`:请求载荷、文档、embedding、事实或响应。
39
+ - `read`:从 memory 或存储中读取。
40
+ - `write`:持久化、索引、笔记或 memory 更新。
41
+ - `async`:事件或队列工作。
42
+ - `feedback`:循环、重试、细化或推理回路。
43
+
44
+ 出现两种以上 flow 时,渲染器会自动输出 flow legend。连线标签保持简短,密集分组、标题标签和节点内部区域用 `waypoints` 绕开。
45
+
46
+ ## 系统蓝图工作流
47
+
48
+ 生成展示级系统蓝图、部署拓扑、集成关系图、Agent runtime 视图、memory/recall 图或 before/after 架构对比时,使用 architecture 路线。先抽取紧凑的系统模型,再绘图:
49
+
50
+ - 入口层:浏览器、移动端、CLI、webhook、调度器或 agent/session 入口。
51
+ - 应用层:网关、前端应用、后端服务、worker、编排层、运行时宿主和工具适配器。
52
+ - 数据层:数据库、对象存储、缓存、向量库、队列、事件总线、日志和分析存储。
53
+ - 外部依赖:身份提供方、AI 模型、支付/邮件服务、SaaS API、云服务、设计工具或运行时连接器。
54
+ - 身份与信任边界:认证、权限、PII 区域、租户边界、私有网络、密钥存储和策略检查。
55
+ - 关键流:请求/控制流、数据流、事件流、部署流、recall/memory flow 或 before/after 迁移流。
56
+
57
+ 第一版蓝图保持可读:
58
+
59
+ - 展示 4-10 个主节点,把低价值文件、类或端点折叠成分组节点。
60
+ - 使用 1-3 个分组边界表达层级、信任区、运行环境或所有权域。
61
+ - 标题和副标题要足够清楚,文件脱离原会话也能分享。
62
+ - 用图例或最多 3 张摘要卡片说明 runtime、data、trust、risks、inputs 或 outcomes。
63
+ - 优先使用语义配色,不做装饰性堆砌;当连线或标签变密时拆成多张图。
64
+
65
+ 面向 README 或干系人交付时,保留 JSON IR 和 HTML 作为可编辑事实源,再导出 SVG/PNG/JPG 产物:
66
+
67
+ ```bash
68
+ node skills/fec-image-generation/scripts/export-diagram.mjs --input docs/architecture/system-blueprint.html --format svg
69
+ node skills/fec-image-generation/scripts/export-diagram.mjs --input docs/architecture/system-blueprint.html --format png --scale 2
70
+ ```
71
+
72
+ 位图导出会优先使用本机已有的 Chromium 系浏览器。环境无法栅格化 SVG 时,交付生成的 HTML/SVG,并说明 PNG/JPG 导出需要本地浏览器。
73
+
74
+ ## JSON IR
75
+
76
+ 所有模式都需要:
77
+
78
+ ```json
79
+ {
80
+ "schema_version": 1,
81
+ "diagram_type": "architecture",
82
+ "meta": {
83
+ "title": "SaaS Architecture",
84
+ "subtitle": "Browser-ready infrastructure overview"
85
+ }
86
+ }
87
+ ```
88
+
89
+ 各模式最小字段:
90
+
91
+ - `architecture`:`nodes`、`connections`;可选 `groups`、`legend`、`summary`。
92
+ - `workflow`:`lanes`、`nodes`、`edges`;可选 `summary`。
93
+ - `sequence`:`participants`、`messages`。
94
+ - `dataflow`:`stages`、`nodes`、`flows`。
95
+ - `lifecycle`:`lanes`、`states`、`transitions`。
96
+
97
+ ID 必须以字母开头,只使用字母、数字、`_` 和 `-`。节点标签保持短小;较长说明放到图外文字或摘要卡片。
98
+
99
+ ## 流程工作流 IR
100
+
101
+ `workflow` 模式适合有明确顺序的流程:它更关注职责、决策、分支和回环,而不是精确的基础设施拓扑。用 `lanes` 表示参与者或系统,用 `nodes` 表示步骤,用 `edges` 表示流转结果。节点仍使用显式 `col` 控制阅读顺序,不依赖隐藏的自动布局引擎。
102
+
103
+ ```json
104
+ {
105
+ "schema_version": 1,
106
+ "diagram_type": "workflow",
107
+ "meta": {
108
+ "title": "Procurement Approval",
109
+ "subtitle": "Request to payment"
110
+ },
111
+ "lanes": [
112
+ { "id": "requester", "label": "Requester" },
113
+ { "id": "system", "label": "System" },
114
+ { "id": "manager", "label": "Manager" }
115
+ ],
116
+ "nodes": [
117
+ { "id": "start", "lane": "requester", "col": 0, "type": "start", "label": "Submit Request", "actor": "Employee" },
118
+ { "id": "classify", "lane": "system", "col": 1, "type": "active", "label": "Classify Spend", "actor": "Policy Engine", "sublabel": "auto rules" },
119
+ { "id": "review", "lane": "manager", "col": 2, "type": "decision", "label": "Approved?", "step": "A" },
120
+ { "id": "pay", "lane": "system", "col": 3, "type": "success", "label": "Issue Payment" },
121
+ { "id": "reject", "lane": "requester", "col": 3, "type": "failure", "label": "Return Request" }
122
+ ],
123
+ "edges": [
124
+ { "from": "start", "to": "classify", "label": "intake", "variant": "emphasis" },
125
+ { "from": "classify", "to": "review", "label": "policy result" },
126
+ { "from": "review", "to": "pay", "label": "yes", "variant": "emphasis" },
127
+ { "from": "review", "to": "reject", "label": "no", "variant": "return", "waypoints": [[650, 396], [520, 396]] }
128
+ ],
129
+ "summary": [
130
+ { "title": "Inputs", "type": "active", "items": ["Purchase request", "Policy threshold"] },
131
+ { "title": "Outcomes", "type": "success", "items": ["Payment issued", "Requester notified"] }
132
+ ]
133
+ }
134
+ ```
135
+
136
+ Workflow 节点字段:
137
+
138
+ - `type`:流程语义使用 `start`、`active`、`waiting`、`decision`、`success`、`failure` 或 `external`。
139
+ - `actor`:可选,显示在节点上方的简短负责人或系统标签。
140
+ - `step`:可选,显示的步骤标记。未提供时,workflow 节点会自动获得顺序编号。
141
+ - `sublabel`、`width`、`height` 和 `yOffset`:可选,用于提升密集泳道中的可读性。
142
+
143
+ Workflow 连线字段:
144
+
145
+ - `variant`:主路径使用 `emphasis`,回环和返工使用 `return` 或 `dashed`,只有信任或策略检查才使用 `security`。
146
+ - `waypoints`:可选 `[x, y]` 点,用于异常路径、跨行连接或需要避开标签和节点的回环。
147
+
148
+ `summary` 用于简短记录前置条件、输入/输出或工具等流程元信息。长说明放在 SVG 外,避免节点标签不可读。
149
+
150
+ ## Architecture IR
151
+
152
+ 架构图使用显式坐标,因为系统图通常需要刻意安排位置、边界和信任区域:
153
+
154
+ ```json
155
+ {
156
+ "schema_version": 1,
157
+ "diagram_type": "architecture",
158
+ "meta": {
159
+ "title": "SaaS Architecture",
160
+ "subtitle": "Browser-ready infrastructure overview"
161
+ },
162
+ "visual": {
163
+ "style": "blueprint"
164
+ },
165
+ "groups": [
166
+ { "id": "cloud", "label": "Cloud region", "type": "cloud", "x": 170, "y": 50, "width": 620, "height": 280 }
167
+ ],
168
+ "nodes": [
169
+ { "id": "web", "label": "Web App", "type": "frontend", "x": 48, "y": 160, "sublabel": "React" },
170
+ { "id": "api", "label": "API Gateway", "type": "cloud", "x": 230, "y": 160, "group": "cloud" },
171
+ { "id": "svc", "label": "App Service", "type": "backend", "x": 420, "y": 160, "group": "cloud" },
172
+ { "id": "db", "label": "PostgreSQL", "type": "database", "x": 620, "y": 160, "group": "cloud" }
173
+ ],
174
+ "connections": [
175
+ { "from": "web", "to": "api", "label": "HTTPS", "variant": "emphasis" },
176
+ { "from": "api", "to": "svc", "label": "REST" },
177
+ { "from": "svc", "to": "db", "label": "SQL" }
178
+ ],
179
+ "summary": [
180
+ { "title": "Runtime", "type": "backend", "items": ["API and worker services", "Managed relational data"] }
181
+ ]
182
+ }
183
+ ```
184
+
185
+ 节点和分组类型支持 `frontend`、`backend`、`database`、`cloud`、`security`、`messagebus`、`external`、`agent`、`model`、`memory`、`vectorstore`、`graphdb`、`tool`、`document`、`queue`、`browser`、`user` 和 `gateway`。连接支持 `default`、`emphasis`、`security`、`dashed` 和 `return`;architecture 连接还可以添加 `flow`。当连线需要绕开边界或标签时,添加 `waypoints`,格式为 `[[x, y], ...]`。
186
+
187
+ 架构图默认根据节点类型生成图例;设置 `legend: false` 可关闭。自定义图例使用 `{ "label": "...", "type": "..." }`。`summary` 最多渲染 3 张图下摘要卡片,不进入 layout manifest,PNG QA 聚焦主图。
188
+
189
+ ## 架构图布局规则
190
+
191
+ - 分组用于表达云区域、集群、信任边界或安全域,不作为装饰面板。
192
+ - 图例放在所有边界之外或下方;空间不足时增大坐标和画布,不压缩文字。
193
+ - 事件总线用 `messagebus` 节点,放在服务之间的空隙。
194
+ - 鉴权、令牌、策略或信任边界流使用 `security` 连接。
195
+ - 网关扇出到多个服务时,优先用 `waypoints` 控制路径,避免密集交叉线。
196
+ - 如果总览图需要多个密集簇,或必须缩小文字才放得下,应拆成总览图加细节图。
197
+
198
+ ## 渲染命令
199
+
200
+ ```bash
201
+ node skills/fec-image-generation/scripts/tech-diagram-render.mjs \
202
+ --input diagram.json \
203
+ --output diagram.html \
204
+ --type architecture \
205
+ --manifest diagram.layout.json
206
+ ```
207
+
208
+ 生成的 HTML 是自包含文件,包含:
209
+
210
+ - Inline SVG。
211
+ - CSS 变量暗/亮主题。
212
+ - 浏览器内主题切换、SVG 下载、打印/PDF 控制。
213
+ - 可选 layout manifest,用于 PNG QA。
214
+
215
+ ## QA 和修复
216
+
217
+ 导出 PNG 后运行:
218
+
219
+ ```bash
220
+ node skills/fec-image-generation/scripts/png-qa.mjs \
221
+ --png diagram.png \
222
+ --manifest diagram.layout.json \
223
+ --format markdown
224
+ ```
225
+
226
+ 修复应回到 JSON 源或渲染尺寸:
227
+
228
+ - 重叠:拆分密集分组,或增加节点/分组间距。
229
+ - 标签截断:缩短标签、添加 `sublabel` 或加宽节点。
230
+ - 连线穿过标签:减少边标签,添加 `waypoints`,或移动节点。
231
+ - 流向过密:拆成总览图和细节图。
232
+ - 边缘裁剪:增加输出空间或简化路径。
233
+
234
+ ## 交付说明
235
+
236
+ 交付 `.html` 源和用户要求的 SVG/PNG/JPG。说明使用的路线、源文件、导出文件、QA 结果,以及仍需人工确认的命名或领域假设。
@@ -0,0 +1,30 @@
1
+ # PNG 质检与自动修复
2
+
3
+ ## 循环
4
+
5
+ 1. 从可编辑源文件或图像工作流导出 PNG。
6
+ 2. 目视检查 PNG。
7
+ 3. 有 manifest 时,带 manifest 运行 `png-qa.mjs`。
8
+ 4. 将每个问题转化为源文件、提示词或布局变更。
9
+ 5. 默认重复 2 轮;用户要求更多修复尝试时最多 5 轮。
10
+
11
+ ## 问题映射
12
+
13
+ | 问题 | 修复方式 |
14
+ | ----- | ------ |
15
+ | `blank-image` | 检查导出目标、渲染器错误、隐藏图层、透明填充或图像生成失败。 |
16
+ | `edge-clipping` | 增加画布留白、扩大 SVG viewBox、降低主体缩放,或导出更大的画幅。 |
17
+ | `box-overlap` | 增加间距、重排为网格/图层、拆分簇,或缩短标签。 |
18
+ | `box-out-of-bounds` | 将节点移入画布,或增大画布尺寸。 |
19
+ | `label-overflow` | 文本换行、加宽框体、减少文案,或同时增大字体/容器尺寸。 |
20
+ | `connector-through-label` | 在框体周围添加 waypoints、移动标签,或使用正交布线。 |
21
+ | `connector-stacking` | 偏移平行连接线,或用带标签的分组路径替代重复线条。 |
22
+ | `manifest-canvas-mismatch` | 根据最终导出尺寸重新生成 manifest。 |
23
+
24
+ ## Manifest 质量
25
+
26
+ 只有当 manifest 坐标与导出的 PNG 匹配时,辅助脚本才能判断重叠和连接线问题。若 manifest 过期,先修复 manifest,再重新运行 QA。
27
+
28
+ ## 报告要求
29
+
30
+ 报告 QA 轮数和最终问题列表。若由于源渲染器无法暴露布局坐标而仍有遗留问题,说明哪些检查只能基于图像,哪些需要人工视觉复核。
@@ -0,0 +1,364 @@
1
+ #!/usr/bin/env node
2
+ // @ts-check
3
+
4
+ import { spawnSync } from "node:child_process";
5
+ import fs from "node:fs";
6
+ import os from "node:os";
7
+ import path from "node:path";
8
+ import { pathToFileURL } from "node:url";
9
+
10
+ const SUPPORTED_FORMATS = new Set(["svg", "png", "jpg", "jpeg"]);
11
+ const JPEG_FORMATS = new Set(["jpg", "jpeg"]);
12
+
13
+ try {
14
+ const args = parseArgs(process.argv.slice(2));
15
+ const inputPath = path.resolve(requireArg(args, "input"));
16
+ const format = requireArg(args, "format").toLowerCase();
17
+ const scale = args.scale === undefined ? 2 : parseScale(args.scale);
18
+ const background = args.background ?? "#0f172a";
19
+
20
+ if (!SUPPORTED_FORMATS.has(format)) {
21
+ throw usageError(`Unsupported --format "${format}". Expected svg, png, jpg, or jpeg.`);
22
+ }
23
+ if (!fs.existsSync(inputPath)) {
24
+ throw usageError(`Input file does not exist: ${inputPath}`);
25
+ }
26
+
27
+ const svg = extractSvg(inputPath);
28
+ const outputPath = path.resolve(resolveOutputPath(inputPath, format, args.output));
29
+
30
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
31
+ if (format === "svg") {
32
+ fs.writeFileSync(outputPath, `${svg.trim()}\n`, "utf8");
33
+ } else {
34
+ exportRaster(svg, outputPath, format, scale, background);
35
+ }
36
+
37
+ console.log(`Exported ${format.toUpperCase()} diagram: ${outputPath}`);
38
+ } catch (error) {
39
+ console.error(error instanceof Error ? error.message : String(error));
40
+ process.exitCode = 1;
41
+ }
42
+
43
+ /**
44
+ * @param {string[]} argv
45
+ * @returns {Record<string, string | undefined>}
46
+ */
47
+ function parseArgs(argv) {
48
+ /** @type {Record<string, string | undefined>} */
49
+ const parsed = {};
50
+ for (let index = 0; index < argv.length; index += 1) {
51
+ const token = argv[index];
52
+ if (!token.startsWith("--")) {
53
+ throw usageError(`Unexpected positional argument "${token}".`);
54
+ }
55
+ const key = token.slice(2);
56
+ const value = argv[index + 1];
57
+ if (!value || value.startsWith("--")) {
58
+ throw usageError(`Missing value for --${key}.`);
59
+ }
60
+ parsed[key] = value;
61
+ index += 1;
62
+ }
63
+ return parsed;
64
+ }
65
+
66
+ /**
67
+ * @param {Record<string, string | undefined>} args
68
+ * @param {string} key
69
+ */
70
+ function requireArg(args, key) {
71
+ const value = args[key];
72
+ if (!value) throw usageError(`Missing required --${key}.`);
73
+ return value;
74
+ }
75
+
76
+ /**
77
+ * @param {string} value
78
+ */
79
+ function parseScale(value) {
80
+ const scale = Number(value);
81
+ if (!Number.isFinite(scale) || scale <= 0) {
82
+ throw usageError("--scale must be a positive number.");
83
+ }
84
+ return scale;
85
+ }
86
+
87
+ /**
88
+ * @param {string} inputPath
89
+ * @param {string} format
90
+ * @param {string | undefined} output
91
+ */
92
+ function resolveOutputPath(inputPath, format, output) {
93
+ if (output) return output;
94
+ const extension = JPEG_FORMATS.has(format) ? ".jpg" : `.${format}`;
95
+ return inputPath.replace(/\.[^.\\/]+$/, "") + extension;
96
+ }
97
+
98
+ /**
99
+ * @param {string} inputPath
100
+ */
101
+ function extractSvg(inputPath) {
102
+ const content = fs.readFileSync(inputPath, "utf8");
103
+ if (inputPath.toLowerCase().endsWith(".svg")) {
104
+ if (!/<svg[\s>]/i.test(content)) {
105
+ throw usageError("SVG input does not contain an <svg> root.");
106
+ }
107
+ return content;
108
+ }
109
+
110
+ const svgStart = content.search(/<svg[\s>]/i);
111
+ if (svgStart === -1) {
112
+ throw usageError("HTML input does not contain an inline <svg> element.");
113
+ }
114
+ const afterStart = content.slice(svgStart);
115
+ const svgEnd = afterStart.search(/<\/svg>/i);
116
+ if (svgEnd === -1) {
117
+ throw usageError("HTML input contains an <svg> start tag without a closing </svg>.");
118
+ }
119
+ return afterStart.slice(0, svgEnd + "</svg>".length);
120
+ }
121
+
122
+ /**
123
+ * @param {string} svg
124
+ * @param {string} outputPath
125
+ * @param {string} format
126
+ * @param {number} scale
127
+ * @param {string} background
128
+ */
129
+ function exportRaster(svg, outputPath, format, scale, background) {
130
+ const browser = findBrowser();
131
+ if (!browser) {
132
+ throw usageError(
133
+ "PNG/JPG export requires a local Chromium browser (Chrome, Edge, Chromium, Brave, or Vivaldi) because Node.js has no built-in SVG rasterizer. Export SVG instead, or install a Chromium browser and rerun this command.",
134
+ );
135
+ }
136
+
137
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "fec-diagram-export-"));
138
+ const htmlPath = path.join(tempDir, "diagram.html");
139
+ const screenshotPath = path.join(tempDir, "diagram.png");
140
+ const { width, height } = measureSvg(svg);
141
+ const viewportWidth = Math.ceil(width * scale);
142
+ const viewportHeight = Math.ceil(height * scale);
143
+
144
+ try {
145
+ fs.writeFileSync(htmlPath, renderScreenshotHtml(svg, width, height, scale, background), "utf8");
146
+
147
+ const result = spawnSync(browser, [
148
+ "--headless=new",
149
+ "--disable-gpu",
150
+ "--hide-scrollbars",
151
+ `--window-size=${viewportWidth},${viewportHeight}`,
152
+ `--screenshot=${screenshotPath}`,
153
+ pathToFileURL(htmlPath).href,
154
+ ], {
155
+ encoding: "utf8",
156
+ timeout: 30000,
157
+ windowsHide: true,
158
+ });
159
+
160
+ if (result.status !== 0 || !fs.existsSync(screenshotPath)) {
161
+ throw usageError(`Browser raster export failed: ${result.stderr || result.stdout || `exit code ${result.status}`}`.trim());
162
+ }
163
+
164
+ if (JPEG_FORMATS.has(format)) {
165
+ convertPngToJpeg(screenshotPath, outputPath);
166
+ } else {
167
+ fs.copyFileSync(screenshotPath, outputPath);
168
+ }
169
+ } finally {
170
+ fs.rmSync(tempDir, { recursive: true, force: true });
171
+ }
172
+ }
173
+
174
+ /**
175
+ * @param {string} pngPath
176
+ * @param {string} outputPath
177
+ */
178
+ function convertPngToJpeg(pngPath, outputPath) {
179
+ const converters = [
180
+ () => convertWithMagick(pngPath, outputPath),
181
+ () => convertWithFfmpeg(pngPath, outputPath),
182
+ () => process.platform === "win32" ? convertWithPowerShell(pngPath, outputPath) : false,
183
+ () => process.platform === "darwin" ? convertWithSips(pngPath, outputPath) : false,
184
+ ];
185
+
186
+ for (const convert of converters) {
187
+ try {
188
+ if (convert() && fs.existsSync(outputPath) && fs.statSync(outputPath).size > 0) return;
189
+ } catch {
190
+ // Try the next system converter.
191
+ }
192
+ }
193
+
194
+ throw usageError("JPG/JPEG export needs a local image converter after Chromium captures the SVG. Install ImageMagick, FFmpeg, macOS sips, or use SVG/PNG output.");
195
+ }
196
+
197
+ /**
198
+ * @param {string} pngPath
199
+ * @param {string} outputPath
200
+ */
201
+ function convertWithMagick(pngPath, outputPath) {
202
+ for (const command of ["magick", "convert"]) {
203
+ const result = spawnSync(command, [pngPath, "-background", "white", "-alpha", "remove", "-quality", "95", outputPath], {
204
+ encoding: "utf8",
205
+ timeout: 15000,
206
+ windowsHide: true,
207
+ });
208
+ if (result.status === 0) return true;
209
+ }
210
+ return false;
211
+ }
212
+
213
+ /**
214
+ * @param {string} pngPath
215
+ * @param {string} outputPath
216
+ */
217
+ function convertWithFfmpeg(pngPath, outputPath) {
218
+ const result = spawnSync("ffmpeg", ["-y", "-i", pngPath, "-q:v", "2", outputPath], {
219
+ encoding: "utf8",
220
+ timeout: 15000,
221
+ windowsHide: true,
222
+ });
223
+ return result.status === 0;
224
+ }
225
+
226
+ /**
227
+ * @param {string} pngPath
228
+ * @param {string} outputPath
229
+ */
230
+ function convertWithPowerShell(pngPath, outputPath) {
231
+ const script = [
232
+ "Add-Type -AssemblyName System.Drawing",
233
+ `$img = [System.Drawing.Image]::FromFile(${quotePowerShell(pngPath)})`,
234
+ "$bmp = New-Object System.Drawing.Bitmap $img.Width, $img.Height",
235
+ "$graphics = [System.Drawing.Graphics]::FromImage($bmp)",
236
+ "$graphics.Clear([System.Drawing.Color]::White)",
237
+ "$graphics.DrawImage($img, 0, 0, $img.Width, $img.Height)",
238
+ `$bmp.Save(${quotePowerShell(outputPath)}, [System.Drawing.Imaging.ImageFormat]::Jpeg)`,
239
+ "$graphics.Dispose(); $bmp.Dispose(); $img.Dispose()",
240
+ ].join("; ");
241
+ const result = spawnSync("powershell", ["-NoProfile", "-Command", script], {
242
+ encoding: "utf8",
243
+ timeout: 15000,
244
+ windowsHide: true,
245
+ });
246
+ return result.status === 0;
247
+ }
248
+
249
+ /**
250
+ * @param {string} pngPath
251
+ * @param {string} outputPath
252
+ */
253
+ function convertWithSips(pngPath, outputPath) {
254
+ fs.copyFileSync(pngPath, outputPath);
255
+ const result = spawnSync("sips", ["-s", "format", "jpeg", outputPath, "--out", outputPath], {
256
+ encoding: "utf8",
257
+ timeout: 15000,
258
+ });
259
+ return result.status === 0;
260
+ }
261
+
262
+ function findBrowser() {
263
+ const envBrowser = process.env.CHROME_PATH || process.env.EDGE_PATH || process.env.BROWSER;
264
+ const candidates = [
265
+ envBrowser,
266
+ process.platform === "win32" ? "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" : undefined,
267
+ process.platform === "win32" ? "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" : undefined,
268
+ process.platform === "win32" ? "C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe" : undefined,
269
+ process.platform === "win32" ? "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe" : undefined,
270
+ process.platform === "darwin" ? "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" : undefined,
271
+ process.platform === "darwin" ? "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge" : undefined,
272
+ "google-chrome",
273
+ "google-chrome-stable",
274
+ "chromium",
275
+ "chromium-browser",
276
+ "microsoft-edge",
277
+ "msedge",
278
+ "brave-browser",
279
+ "vivaldi",
280
+ ].filter(Boolean);
281
+
282
+ for (const candidate of candidates) {
283
+ if (typeof candidate !== "string") continue;
284
+ if (path.isAbsolute(candidate) && fs.existsSync(candidate)) return candidate;
285
+ if (!path.isAbsolute(candidate)) {
286
+ const result = spawnSync(candidate, ["--version"], { encoding: "utf8", timeout: 5000, windowsHide: true });
287
+ if (result.status === 0) return candidate;
288
+ }
289
+ }
290
+ return null;
291
+ }
292
+
293
+ /**
294
+ * @param {string} value
295
+ */
296
+ function quotePowerShell(value) {
297
+ return `'${value.replace(/'/g, "''")}'`;
298
+ }
299
+
300
+ /**
301
+ * @param {string} svg
302
+ */
303
+ function measureSvg(svg) {
304
+ const openTag = svg.match(/<svg\b[^>]*>/i)?.[0] ?? "";
305
+ const width = numberAttr(openTag, "width");
306
+ const height = numberAttr(openTag, "height");
307
+ if (width && height) return { width, height };
308
+
309
+ const viewBox = openTag.match(/\bviewBox=(["'])(.*?)\1/i)?.[2]?.trim().split(/\s+/).map(Number);
310
+ if (viewBox && viewBox.length === 4 && viewBox.every(Number.isFinite)) {
311
+ return { width: viewBox[2], height: viewBox[3] };
312
+ }
313
+ return { width: 1280, height: 720 };
314
+ }
315
+
316
+ /**
317
+ * @param {string} tag
318
+ * @param {string} name
319
+ */
320
+ function numberAttr(tag, name) {
321
+ const value = tag.match(new RegExp(`\\b${name}=(["'])(.*?)\\1`, "i"))?.[2];
322
+ if (!value) return null;
323
+ const number = Number.parseFloat(value);
324
+ return Number.isFinite(number) && number > 0 ? number : null;
325
+ }
326
+
327
+ /**
328
+ * @param {string} svg
329
+ * @param {number} width
330
+ * @param {number} height
331
+ * @param {number} scale
332
+ * @param {string} background
333
+ */
334
+ function renderScreenshotHtml(svg, width, height, scale, background) {
335
+ return `<!doctype html>
336
+ <html lang="en">
337
+ <head>
338
+ <meta charset="utf-8">
339
+ <style>
340
+ html, body {
341
+ margin: 0;
342
+ width: ${Math.ceil(width * scale)}px;
343
+ height: ${Math.ceil(height * scale)}px;
344
+ overflow: hidden;
345
+ background: ${background};
346
+ }
347
+ svg {
348
+ display: block;
349
+ width: ${Math.ceil(width * scale)}px;
350
+ height: ${Math.ceil(height * scale)}px;
351
+ }
352
+ </style>
353
+ </head>
354
+ <body>${svg}</body>
355
+ </html>
356
+ `;
357
+ }
358
+
359
+ /**
360
+ * @param {string} message
361
+ */
362
+ function usageError(message) {
363
+ return new Error(message);
364
+ }