@bovinphang/frontend-craft 2.6.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.
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +72 -1
- package/CHANGELOG.zh-CN.md +71 -1
- package/README.md +10 -6
- package/README.openclaw.md +100 -42
- package/README.openclaw.zh-CN.md +100 -42
- package/README.zh-CN.md +10 -6
- package/agents/fec-architect.md +70 -70
- package/agents/fec-code-reviewer.md +82 -82
- package/agents/fec-debugger.md +20 -20
- package/agents/fec-design-token-mapper.md +36 -36
- package/agents/fec-doc-updater.md +13 -13
- package/agents/fec-e2e-runner.md +45 -45
- package/agents/fec-figma-implementer.md +59 -59
- package/agents/fec-performance-optimizer.md +128 -128
- package/agents/fec-refactor-cleaner.md +14 -14
- package/agents/fec-security-reviewer.md +66 -67
- package/agents/fec-test-planner.md +27 -27
- package/agents/fec-typescript-reviewer.md +88 -88
- package/agents/fec-ui-checker.md +74 -74
- package/commands/fec-debug.md +19 -19
- package/commands/fec-doc-sync.md +11 -11
- package/commands/fec-init.md +37 -38
- package/commands/fec-plan.md +58 -58
- package/commands/fec-refactor-clean.md +11 -11
- package/commands/fec-review.md +41 -41
- package/commands/fec-scaffold.md +41 -41
- package/commands/fec-tdd.md +13 -13
- package/dist/bin/frontend-craft.js +29 -27
- package/docs/example-prompts.md +84 -69
- package/docs/ja-JP/README.md +56 -52
- package/docs/ko-KR/README.md +45 -41
- package/docs/project-structure.md +19 -7
- package/docs/superpowers/plans/2026-05-29-fec-debug.md +491 -0
- package/docs/superpowers/specs/2026-05-29-fec-debug-design.md +340 -0
- package/docs/zh-CN/example-prompts.md +84 -69
- package/docs/zh-CN/project-structure.md +14 -5
- package/docs/zh-TW/README.md +33 -29
- package/localized/zh-CN/agents/fec-architect.md +125 -0
- package/localized/zh-CN/agents/fec-code-reviewer.md +152 -0
- package/localized/zh-CN/agents/fec-debugger.md +44 -0
- package/localized/zh-CN/agents/fec-design-token-mapper.md +75 -0
- package/localized/zh-CN/agents/fec-doc-updater.md +30 -0
- package/localized/zh-CN/agents/fec-e2e-runner.md +107 -0
- package/localized/zh-CN/agents/fec-figma-implementer.md +104 -0
- package/localized/zh-CN/agents/fec-performance-optimizer.md +293 -0
- package/localized/zh-CN/agents/fec-refactor-cleaner.md +32 -0
- package/localized/zh-CN/agents/fec-security-reviewer.md +116 -0
- package/localized/zh-CN/agents/fec-test-planner.md +50 -0
- package/localized/zh-CN/agents/fec-typescript-reviewer.md +142 -0
- package/localized/zh-CN/agents/fec-ui-checker.md +120 -0
- package/localized/zh-CN/commands/fec-debug.md +30 -0
- package/localized/zh-CN/commands/fec-doc-sync.md +19 -0
- package/localized/zh-CN/commands/fec-init.md +70 -0
- package/localized/zh-CN/commands/fec-plan.md +94 -0
- package/localized/zh-CN/commands/fec-refactor-clean.md +19 -0
- package/localized/zh-CN/commands/fec-review.md +66 -0
- package/localized/zh-CN/commands/fec-scaffold.md +205 -0
- package/localized/zh-CN/commands/fec-tdd.md +21 -0
- package/localized/zh-CN/skills/TEMPLATE.md +155 -0
- package/localized/zh-CN/skills/eval_queries.json +1013 -0
- package/localized/zh-CN/skills/fec-accessibility-check/SKILL.md +39 -0
- package/localized/zh-CN/skills/fec-accessibility-check/references/report-template.md +23 -0
- package/localized/zh-CN/skills/fec-accessibility-check/references/screen-reader-testing.md +33 -0
- package/localized/zh-CN/skills/fec-alchemy/SKILL.md +74 -0
- package/localized/zh-CN/skills/fec-alchemy/assets/absorption-plan-template.md +47 -0
- package/localized/zh-CN/skills/fec-alchemy/assets/intake-template.md +55 -0
- package/localized/zh-CN/skills/fec-alchemy/assets/review-checklist.md +31 -0
- package/localized/zh-CN/skills/fec-alchemy/references/methodology.md +94 -0
- package/localized/zh-CN/skills/fec-alchemy/references/originality-and-licensing.md +57 -0
- package/localized/zh-CN/skills/fec-api-integration/SKILL.md +78 -0
- package/localized/zh-CN/skills/fec-api-integration/references/integration-patterns.md +80 -0
- package/localized/zh-CN/skills/fec-backend-requirements-handoff/SKILL.md +45 -0
- package/localized/zh-CN/skills/fec-browser-storage/SKILL.md +34 -0
- package/localized/zh-CN/skills/fec-browser-storage/references/storage-patterns.md +65 -0
- package/localized/zh-CN/skills/fec-canvas-threejs/SKILL.md +66 -0
- package/localized/zh-CN/skills/fec-canvas-threejs/references/rendering-patterns.md +67 -0
- package/localized/zh-CN/skills/fec-canvas-threejs/references/shader-webgl-patterns.md +67 -0
- package/localized/zh-CN/skills/fec-code-review/SKILL.md +143 -0
- package/localized/zh-CN/skills/fec-code-review/references/report-template.md +29 -0
- package/localized/zh-CN/skills/fec-component-testing/SKILL.md +119 -0
- package/localized/zh-CN/skills/fec-data-fetching/SKILL.md +62 -0
- package/localized/zh-CN/skills/fec-data-fetching/references/query-patterns.md +103 -0
- package/localized/zh-CN/skills/fec-debug-framework/SKILL.md +157 -0
- package/localized/zh-CN/skills/fec-debug-framework/references/report-template.md +58 -0
- package/localized/zh-CN/skills/fec-dependency-upgrade/SKILL.md +34 -0
- package/localized/zh-CN/skills/fec-dependency-upgrade/references/dependency-upgrade-workflow.md +56 -0
- package/localized/zh-CN/skills/fec-doc-sync/SKILL.md +39 -0
- package/localized/zh-CN/skills/fec-drawio-studio/SKILL.md +73 -0
- package/localized/zh-CN/skills/fec-drawio-studio/data/THIRD_PARTY_NOTICES.md +10 -0
- package/localized/zh-CN/skills/fec-drawio-studio/data/brand-icons.json +878 -0
- package/localized/zh-CN/skills/fec-drawio-studio/data/shape-index.json +83570 -0
- package/localized/zh-CN/skills/fec-drawio-studio/references/data-residency.md +27 -0
- package/localized/zh-CN/skills/fec-drawio-studio/references/diagram-patterns.md +60 -0
- package/localized/zh-CN/skills/fec-drawio-studio/references/flowchart-quality.md +49 -0
- package/localized/zh-CN/skills/fec-drawio-studio/references/layout-and-export.md +72 -0
- package/localized/zh-CN/skills/fec-drawio-studio/references/troubleshooting.md +29 -0
- package/localized/zh-CN/skills/fec-drawio-studio/references/xml-and-mermaid.md +58 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/brand-symbols.mjs +99 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/diagram-lint.mjs +205 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/diagram-url.mjs +102 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/drawio-export.mjs +134 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/layout-graph.mjs +107 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/png-embed-fix.mjs +26 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-go-packages.mjs +36 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-js-modules.mjs +52 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-python-classes.mjs +30 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-python-modules.mjs +55 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-rust-modules.mjs +35 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/scan-ts-modules.mjs +7 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/shape-query.mjs +121 -0
- package/localized/zh-CN/skills/fec-drawio-studio/scripts/studio-core.mjs +139 -0
- package/localized/zh-CN/skills/fec-drawio-studio/styles/built-in/corporate.json +49 -0
- package/localized/zh-CN/skills/fec-drawio-studio/styles/built-in/default.json +49 -0
- package/localized/zh-CN/skills/fec-drawio-studio/styles/built-in/handdrawn.json +49 -0
- package/localized/zh-CN/skills/fec-drawio-studio/styles/schema.json +112 -0
- package/localized/zh-CN/skills/fec-e2e-testing/SKILL.md +42 -0
- package/localized/zh-CN/skills/fec-e2e-testing/references/e2e-ci-reporting.md +62 -0
- package/localized/zh-CN/skills/fec-e2e-testing/references/e2e-special-scenarios.md +52 -0
- package/localized/zh-CN/skills/fec-e2e-testing/references/e2e-visual-regression.md +60 -0
- package/localized/zh-CN/skills/fec-e2e-testing/references/playwright-patterns.md +95 -0
- package/localized/zh-CN/skills/fec-form-handling/SKILL.md +76 -0
- package/localized/zh-CN/skills/fec-form-handling/references/advanced-form-patterns.md +101 -0
- package/localized/zh-CN/skills/fec-image-generation/SKILL.md +80 -0
- package/localized/zh-CN/skills/fec-image-generation/assets/interactive-diagram.html +371 -0
- package/localized/zh-CN/skills/fec-image-generation/references/artifact-routing.md +80 -0
- package/localized/zh-CN/skills/fec-image-generation/references/diagram-workflows.md +74 -0
- package/localized/zh-CN/skills/fec-image-generation/references/html-technical-diagrams.md +236 -0
- package/localized/zh-CN/skills/fec-image-generation/references/png-qa-autofix.md +30 -0
- package/localized/zh-CN/skills/fec-image-generation/scripts/export-diagram.mjs +364 -0
- package/localized/zh-CN/skills/fec-image-generation/scripts/interactive-diagram-server.mjs +654 -0
- package/localized/zh-CN/skills/fec-image-generation/scripts/png-qa.mjs +431 -0
- package/localized/zh-CN/skills/fec-image-generation/scripts/tech-diagram-render.mjs +1397 -0
- package/localized/zh-CN/skills/fec-implement-from-design/SKILL.md +129 -0
- package/localized/zh-CN/skills/fec-implement-from-design/references/design-plan-template.md +36 -0
- package/localized/zh-CN/skills/fec-legacy-to-modern-migration/SKILL.md +46 -0
- package/localized/zh-CN/skills/fec-legacy-to-modern-migration/references/migration-execution-checklist.md +110 -0
- package/localized/zh-CN/skills/fec-legacy-to-modern-migration/references/migration-report-template.md +41 -0
- package/localized/zh-CN/skills/fec-legacy-to-modern-migration/references/migration-strategy-and-mapping.md +48 -0
- package/localized/zh-CN/skills/fec-legacy-web-standard/SKILL.md +35 -0
- package/localized/zh-CN/skills/fec-legacy-web-standard/references/legacy-patterns.md +85 -0
- package/localized/zh-CN/skills/fec-list-virtualization/SKILL.md +34 -0
- package/localized/zh-CN/skills/fec-list-virtualization/references/virtualization-patterns.md +80 -0
- package/localized/zh-CN/skills/fec-monorepo-project-standard/SKILL.md +142 -0
- package/localized/zh-CN/skills/fec-motion-interaction/SKILL.md +73 -0
- package/localized/zh-CN/skills/fec-motion-interaction/references/motion-patterns.md +112 -0
- package/localized/zh-CN/skills/fec-nextjs-project-standard/SKILL.md +123 -0
- package/localized/zh-CN/skills/fec-nuxt-project-standard/SKILL.md +122 -0
- package/localized/zh-CN/skills/fec-performance-optimization/SKILL.md +80 -0
- package/localized/zh-CN/skills/fec-performance-optimization/references/framework-performance-patterns.md +38 -0
- package/localized/zh-CN/skills/fec-performance-optimization/references/report-template.md +59 -0
- package/localized/zh-CN/skills/fec-pwa-implementation/SKILL.md +35 -0
- package/localized/zh-CN/skills/fec-pwa-implementation/references/manifest-and-icons.md +53 -0
- package/localized/zh-CN/skills/fec-pwa-implementation/references/service-worker-workbox.md +68 -0
- package/localized/zh-CN/skills/fec-react-project-standard/SKILL.md +91 -0
- package/localized/zh-CN/skills/fec-react-project-standard/references/react-performance-patterns.md +35 -0
- package/localized/zh-CN/skills/fec-react-project-standard/references/react-project-structure.md +197 -0
- package/localized/zh-CN/skills/fec-react-project-standard/references/react-quality-patterns.md +131 -0
- package/localized/zh-CN/skills/fec-react-project-standard/references/react-runtime-patterns.md +293 -0
- package/localized/zh-CN/skills/fec-refactor-clean/SKILL.md +51 -0
- package/localized/zh-CN/skills/fec-refactor-clean/references/report-template.md +42 -0
- package/localized/zh-CN/skills/fec-responsive-layout/SKILL.md +34 -0
- package/localized/zh-CN/skills/fec-responsive-layout/references/responsive-layout-patterns.md +70 -0
- package/localized/zh-CN/skills/fec-route-protection/SKILL.md +135 -0
- package/localized/zh-CN/skills/fec-security-review/SKILL.md +38 -0
- package/localized/zh-CN/skills/fec-security-review/references/report-template.md +27 -0
- package/localized/zh-CN/skills/fec-security-review/references/security-checklist.md +64 -0
- package/localized/zh-CN/skills/fec-source-driven-development/SKILL.md +87 -0
- package/localized/zh-CN/skills/fec-state-management/SKILL.md +140 -0
- package/localized/zh-CN/skills/fec-state-management/references/state-patterns.md +109 -0
- package/localized/zh-CN/skills/fec-storybook-component-doc/SKILL.md +37 -0
- package/localized/zh-CN/skills/fec-storybook-component-doc/references/story-patterns.md +118 -0
- package/localized/zh-CN/skills/fec-svg-animation/SKILL.md +148 -0
- package/localized/zh-CN/skills/fec-tailwind-design-system/SKILL.md +34 -0
- package/localized/zh-CN/skills/fec-tailwind-design-system/references/tailwind-system-patterns.md +59 -0
- package/localized/zh-CN/skills/fec-tdd-workflow/SKILL.md +52 -0
- package/localized/zh-CN/skills/fec-testing-strategy/SKILL.md +45 -0
- package/localized/zh-CN/skills/fec-typescript-project-standard/SKILL.md +54 -0
- package/{skills/fec-typescript-type-safety → localized/zh-CN/skills/fec-typescript-project-standard}/references/type-safety-patterns.md +1 -1
- package/{skills/fec-typescript-type-safety/SKILL.md → localized/zh-CN/skills/fec-typescript-project-standard/references/type-safety.md} +5 -14
- package/localized/zh-CN/skills/fec-ui-design/SKILL.md +108 -0
- package/localized/zh-CN/skills/fec-ui-design/data/product-rules.json +231 -0
- package/localized/zh-CN/skills/fec-ui-design/data/stack-ui-rules.json +146 -0
- package/localized/zh-CN/skills/fec-ui-design/data/style-archetypes.json +373 -0
- package/localized/zh-CN/skills/fec-ui-design/data/ux-quality-rules.json +203 -0
- package/localized/zh-CN/skills/fec-ui-design/references/design-intelligence.md +97 -0
- package/localized/zh-CN/skills/fec-ui-design/references/master-page-overrides.md +30 -0
- package/localized/zh-CN/skills/fec-ui-design/references/pre-delivery-checklist.md +39 -0
- package/localized/zh-CN/skills/fec-ui-design/scripts/design-system.mjs +648 -0
- package/localized/zh-CN/skills/fec-validation-fix/SKILL.md +51 -0
- package/localized/zh-CN/skills/fec-validation-fix/references/report-template.md +43 -0
- package/localized/zh-CN/skills/fec-vite-project-standard/SKILL.md +83 -0
- package/localized/zh-CN/skills/fec-vue3-project-standard/SKILL.md +58 -0
- package/localized/zh-CN/skills/fec-vue3-project-standard/references/vue3-composables-routing.md +162 -0
- package/localized/zh-CN/skills/fec-vue3-project-standard/references/vue3-performance-patterns.md +13 -0
- package/localized/zh-CN/skills/fec-vue3-project-standard/references/vue3-project-structure.md +176 -0
- package/localized/zh-CN/skills/fec-vue3-project-standard/references/vue3-state-api-quality.md +216 -0
- package/localized/zh-CN/skills/fec-web-video-presentation/SKILL.md +61 -0
- package/localized/zh-CN/skills/fec-web-video-presentation/data/starter-themes.json +59 -0
- package/localized/zh-CN/skills/fec-web-video-presentation/references/chapter-craft.md +37 -0
- package/localized/zh-CN/skills/fec-web-video-presentation/references/content-plan.md +38 -0
- package/localized/zh-CN/skills/fec-web-video-presentation/references/recording-and-audio.md +33 -0
- package/localized/zh-CN/skills/fec-web-video-presentation/references/theme-system.md +36 -0
- package/localized/zh-CN/skills/fec-web-video-presentation/scripts/create-video-presentation.mjs +430 -0
- package/localized/zh-CN/skills/fec-web-workers/SKILL.md +35 -0
- package/localized/zh-CN/skills/fec-web-workers/references/advanced-workers.md +54 -0
- package/localized/zh-CN/skills/fec-web-workers/references/basic-worker.md +67 -0
- package/localized/zh-CN/skills/metadata.json +1646 -0
- package/localized/zh-CN/skills/relations.json +755 -0
- package/localized/zh-CN/templates/claude/CLAUDE.md +106 -0
- package/localized/zh-CN/templates/claude/settings.json +62 -0
- package/localized/zh-CN/templates/codex/AGENTS.md +105 -0
- package/localized/zh-CN/templates/codex/config.toml +32 -0
- package/localized/zh-CN/templates/openclaw/AGENTS.md +101 -0
- package/localized/zh-CN/templates/openclaw/OPENCLAW-CONFIG.md +12 -0
- package/localized/zh-CN/templates/shared/rules/fec-agent-workflow.md +54 -0
- package/localized/zh-CN/templates/shared/rules/fec-api-layer.md +99 -0
- package/localized/zh-CN/templates/shared/rules/fec-ci-cd.md +40 -0
- package/localized/zh-CN/templates/shared/rules/fec-code-comments.md +33 -0
- package/localized/zh-CN/templates/shared/rules/fec-design-system.md +72 -0
- package/localized/zh-CN/templates/shared/rules/fec-error-handling.md +56 -0
- package/localized/zh-CN/templates/shared/rules/fec-git-conventions.md +73 -0
- package/localized/zh-CN/templates/shared/rules/fec-i18n.md +64 -0
- package/localized/zh-CN/templates/shared/rules/fec-naming-conventions.md +120 -0
- package/localized/zh-CN/templates/shared/rules/fec-performance.md +101 -0
- package/localized/zh-CN/templates/shared/rules/fec-react.md +82 -0
- package/localized/zh-CN/templates/shared/rules/fec-refactoring.md +47 -0
- package/localized/zh-CN/templates/shared/rules/fec-rendering-patterns.md +40 -0
- package/localized/zh-CN/templates/shared/rules/fec-responsive-design.md +50 -0
- package/localized/zh-CN/templates/shared/rules/fec-source-driven-development.md +31 -0
- package/localized/zh-CN/templates/shared/rules/fec-state-management.md +60 -0
- package/localized/zh-CN/templates/shared/rules/fec-testing.md +98 -0
- package/localized/zh-CN/templates/shared/rules/fec-typescript.md +112 -0
- package/localized/zh-CN/templates/shared/rules/fec-vue.md +64 -0
- package/localized/zh-CN/templates/shared/rules/fec-working-modes.md +50 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -3
- package/skills/TEMPLATE.md +74 -74
- package/skills/eval_queries.json +717 -619
- package/skills/fec-accessibility-check/SKILL.md +21 -21
- package/skills/fec-accessibility-check/references/report-template.md +12 -12
- package/skills/fec-accessibility-check/references/screen-reader-testing.md +24 -24
- package/skills/fec-alchemy/SKILL.md +50 -50
- package/skills/fec-alchemy/assets/absorption-plan-template.md +32 -32
- package/skills/fec-alchemy/assets/intake-template.md +55 -55
- package/skills/fec-alchemy/assets/review-checklist.md +23 -23
- package/skills/fec-alchemy/references/methodology.md +66 -66
- package/skills/fec-alchemy/references/originality-and-licensing.md +42 -42
- package/skills/fec-api-integration/SKILL.md +61 -61
- package/skills/fec-api-integration/references/integration-patterns.md +30 -30
- package/skills/fec-backend-requirements-handoff/SKILL.md +45 -0
- package/skills/fec-browser-storage/SKILL.md +16 -16
- package/skills/fec-browser-storage/references/storage-patterns.md +16 -16
- package/skills/fec-canvas-threejs/SKILL.md +21 -21
- package/skills/fec-canvas-threejs/references/rendering-patterns.md +10 -10
- package/skills/fec-canvas-threejs/references/shader-webgl-patterns.md +37 -37
- package/skills/fec-code-review/SKILL.md +94 -94
- package/skills/fec-code-review/references/report-template.md +13 -13
- package/skills/fec-component-testing/SKILL.md +39 -39
- package/skills/fec-data-fetching/SKILL.md +16 -16
- package/skills/fec-data-fetching/references/query-patterns.md +27 -27
- package/skills/fec-debug-framework/SKILL.md +95 -95
- package/skills/fec-debug-framework/references/report-template.md +34 -34
- package/skills/fec-dependency-upgrade/SKILL.md +17 -17
- package/skills/fec-dependency-upgrade/references/dependency-upgrade-workflow.md +31 -31
- package/skills/fec-doc-sync/SKILL.md +23 -23
- package/skills/fec-drawio-studio/SKILL.md +73 -0
- package/skills/fec-drawio-studio/data/THIRD_PARTY_NOTICES.md +10 -0
- package/skills/fec-drawio-studio/data/brand-icons.json +878 -0
- package/skills/fec-drawio-studio/data/shape-index.json +83570 -0
- package/skills/fec-drawio-studio/references/data-residency.md +27 -0
- package/skills/fec-drawio-studio/references/diagram-patterns.md +60 -0
- package/skills/fec-drawio-studio/references/flowchart-quality.md +49 -0
- package/skills/fec-drawio-studio/references/layout-and-export.md +72 -0
- package/skills/fec-drawio-studio/references/troubleshooting.md +29 -0
- package/skills/fec-drawio-studio/references/xml-and-mermaid.md +58 -0
- package/skills/fec-drawio-studio/scripts/brand-symbols.mjs +99 -0
- package/skills/fec-drawio-studio/scripts/diagram-lint.mjs +205 -0
- package/skills/fec-drawio-studio/scripts/diagram-url.mjs +102 -0
- package/skills/fec-drawio-studio/scripts/drawio-export.mjs +134 -0
- package/skills/fec-drawio-studio/scripts/layout-graph.mjs +107 -0
- package/skills/fec-drawio-studio/scripts/png-embed-fix.mjs +26 -0
- package/skills/fec-drawio-studio/scripts/scan-go-packages.mjs +36 -0
- package/skills/fec-drawio-studio/scripts/scan-js-modules.mjs +52 -0
- package/skills/fec-drawio-studio/scripts/scan-python-classes.mjs +30 -0
- package/skills/fec-drawio-studio/scripts/scan-python-modules.mjs +55 -0
- package/skills/fec-drawio-studio/scripts/scan-rust-modules.mjs +35 -0
- package/skills/fec-drawio-studio/scripts/scan-ts-modules.mjs +7 -0
- package/skills/fec-drawio-studio/scripts/shape-query.mjs +121 -0
- package/skills/fec-drawio-studio/scripts/studio-core.mjs +139 -0
- package/skills/fec-drawio-studio/styles/built-in/corporate.json +49 -0
- package/skills/fec-drawio-studio/styles/built-in/default.json +49 -0
- package/skills/fec-drawio-studio/styles/built-in/handdrawn.json +49 -0
- package/skills/fec-drawio-studio/styles/schema.json +112 -0
- package/skills/fec-e2e-testing/SKILL.md +24 -22
- package/skills/fec-e2e-testing/references/e2e-ci-reporting.md +62 -0
- package/skills/fec-e2e-testing/references/e2e-special-scenarios.md +52 -0
- package/skills/fec-e2e-testing/references/e2e-visual-regression.md +60 -0
- package/skills/fec-e2e-testing/references/playwright-patterns.md +6 -6
- package/skills/fec-form-handling/SKILL.md +21 -21
- package/skills/fec-form-handling/references/advanced-form-patterns.md +41 -41
- package/skills/fec-image-generation/SKILL.md +81 -0
- package/skills/fec-image-generation/assets/interactive-diagram.html +371 -0
- package/skills/fec-image-generation/references/artifact-routing.md +80 -0
- package/skills/fec-image-generation/references/diagram-workflows.md +74 -0
- package/skills/fec-image-generation/references/html-technical-diagrams.md +236 -0
- package/skills/fec-image-generation/references/png-qa-autofix.md +30 -0
- package/skills/fec-image-generation/scripts/export-diagram.mjs +364 -0
- package/skills/fec-image-generation/scripts/interactive-diagram-server.mjs +654 -0
- package/skills/fec-image-generation/scripts/png-qa.mjs +431 -0
- package/skills/fec-image-generation/scripts/tech-diagram-render.mjs +1397 -0
- package/skills/fec-implement-from-design/SKILL.md +81 -74
- package/skills/fec-implement-from-design/references/design-plan-template.md +16 -16
- package/skills/fec-legacy-to-modern-migration/SKILL.md +29 -173
- package/skills/fec-legacy-to-modern-migration/references/migration-execution-checklist.md +110 -0
- package/skills/fec-legacy-to-modern-migration/references/migration-report-template.md +37 -37
- package/skills/fec-legacy-to-modern-migration/references/migration-strategy-and-mapping.md +48 -0
- package/skills/fec-legacy-web-standard/SKILL.md +17 -17
- package/skills/fec-legacy-web-standard/references/legacy-patterns.md +16 -16
- package/skills/fec-list-virtualization/SKILL.md +16 -16
- package/skills/fec-list-virtualization/references/virtualization-patterns.md +31 -31
- package/skills/fec-monorepo-project-standard/SKILL.md +52 -52
- package/skills/fec-motion-interaction/SKILL.md +51 -44
- package/skills/fec-motion-interaction/references/motion-patterns.md +11 -11
- package/skills/fec-nextjs-project-standard/SKILL.md +64 -58
- package/skills/fec-nuxt-project-standard/SKILL.md +57 -57
- package/skills/fec-performance-optimization/SKILL.md +54 -50
- package/skills/fec-performance-optimization/references/framework-performance-patterns.md +38 -0
- package/skills/fec-performance-optimization/references/report-template.md +34 -28
- package/skills/fec-pwa-implementation/SKILL.md +17 -17
- package/skills/fec-pwa-implementation/references/manifest-and-icons.md +12 -12
- package/skills/fec-pwa-implementation/references/service-worker-workbox.md +13 -13
- package/skills/fec-react-project-standard/SKILL.md +72 -64
- package/skills/fec-react-project-standard/references/react-performance-patterns.md +35 -0
- package/skills/fec-react-project-standard/references/react-project-structure.md +197 -0
- package/skills/fec-react-project-standard/references/react-quality-patterns.md +131 -0
- package/skills/fec-react-project-standard/references/react-runtime-patterns.md +293 -0
- package/skills/fec-refactor-clean/SKILL.md +30 -30
- package/skills/fec-refactor-clean/references/report-template.md +23 -23
- package/skills/fec-responsive-layout/SKILL.md +17 -17
- package/skills/fec-responsive-layout/references/responsive-layout-patterns.md +39 -28
- package/skills/fec-route-protection/SKILL.md +26 -26
- package/skills/fec-security-review/SKILL.md +20 -20
- package/skills/fec-security-review/references/report-template.md +12 -12
- package/skills/fec-security-review/references/security-checklist.md +27 -27
- package/skills/fec-source-driven-development/SKILL.md +66 -40
- package/skills/fec-state-management/SKILL.md +34 -34
- package/skills/fec-state-management/references/state-patterns.md +19 -19
- package/skills/fec-storybook-component-doc/SKILL.md +19 -19
- package/skills/fec-storybook-component-doc/references/story-patterns.md +12 -12
- package/skills/fec-svg-animation/SKILL.md +32 -32
- package/skills/fec-tailwind-design-system/SKILL.md +17 -17
- package/skills/fec-tailwind-design-system/references/tailwind-system-patterns.md +36 -32
- package/skills/fec-tdd-workflow/SKILL.md +28 -28
- package/skills/fec-testing-strategy/SKILL.md +29 -29
- package/skills/fec-typescript-project-standard/SKILL.md +54 -0
- package/skills/fec-typescript-project-standard/references/type-safety-patterns.md +102 -0
- package/skills/fec-typescript-project-standard/references/type-safety.md +148 -0
- package/skills/fec-ui-design/SKILL.md +90 -72
- package/skills/fec-ui-design/data/style-archetypes.json +40 -0
- package/skills/fec-ui-design/data/ux-quality-rules.json +35 -0
- package/skills/fec-ui-design/references/design-intelligence.md +81 -21
- package/skills/fec-ui-design/references/master-page-overrides.md +15 -15
- package/skills/fec-ui-design/references/pre-delivery-checklist.md +38 -32
- package/skills/fec-ui-design/scripts/design-system.mjs +119 -1
- package/skills/fec-validation-fix/SKILL.md +26 -26
- package/skills/fec-validation-fix/references/report-template.md +25 -25
- package/skills/fec-vite-project-standard/SKILL.md +39 -39
- package/skills/fec-vue3-project-standard/SKILL.md +39 -30
- package/skills/fec-vue3-project-standard/references/vue3-composables-routing.md +163 -0
- package/skills/fec-vue3-project-standard/references/vue3-performance-patterns.md +13 -0
- package/skills/fec-vue3-project-standard/references/vue3-project-structure.md +177 -0
- package/skills/fec-vue3-project-standard/references/vue3-state-api-quality.md +216 -0
- package/skills/fec-web-video-presentation/SKILL.md +61 -0
- package/skills/fec-web-video-presentation/data/starter-themes.json +59 -0
- package/skills/fec-web-video-presentation/references/chapter-craft.md +37 -0
- package/skills/fec-web-video-presentation/references/content-plan.md +38 -0
- package/skills/fec-web-video-presentation/references/recording-and-audio.md +33 -0
- package/skills/fec-web-video-presentation/references/theme-system.md +36 -0
- package/skills/fec-web-video-presentation/scripts/create-video-presentation.mjs +430 -0
- package/skills/fec-web-workers/SKILL.md +16 -16
- package/skills/fec-web-workers/references/advanced-workers.md +13 -13
- package/skills/fec-web-workers/references/basic-worker.md +8 -8
- package/skills/metadata.json +402 -220
- package/skills/relations.json +120 -25
- package/templates/claude/CLAUDE.md +60 -60
- package/templates/codex/AGENTS.md +76 -76
- package/templates/codex/config.toml +4 -4
- package/templates/openclaw/AGENTS.md +68 -68
- package/templates/openclaw/OPENCLAW-CONFIG.md +8 -8
- package/templates/shared/rules/fec-agent-workflow.md +40 -40
- package/templates/shared/rules/fec-api-layer.md +52 -52
- package/templates/shared/rules/fec-ci-cd.md +29 -117
- package/templates/shared/rules/fec-code-comments.md +22 -22
- package/templates/shared/rules/fec-design-system.md +65 -241
- package/templates/shared/rules/fec-error-handling.md +41 -185
- package/templates/shared/rules/fec-git-conventions.md +42 -42
- package/templates/shared/rules/fec-i18n.md +48 -96
- package/templates/shared/rules/fec-naming-conventions.md +91 -91
- package/templates/shared/rules/fec-performance.md +78 -78
- package/templates/shared/rules/fec-react.md +58 -58
- package/templates/shared/rules/fec-refactoring.md +34 -30
- package/templates/shared/rules/fec-rendering-patterns.md +40 -183
- package/templates/shared/rules/fec-responsive-design.md +37 -214
- package/templates/shared/rules/fec-source-driven-development.md +22 -22
- package/templates/shared/rules/fec-state-management.md +45 -148
- package/templates/shared/rules/fec-testing.md +64 -64
- package/templates/shared/rules/fec-typescript.md +98 -341
- package/templates/shared/rules/fec-vue.md +42 -42
- package/templates/shared/rules/fec-working-modes.md +34 -34
- package/skills/fec-e2e-testing/references/e2e-advanced.md +0 -176
- package/skills/fec-react-project-standard/references/react-project-details.md +0 -642
- package/skills/fec-vue3-project-standard/references/vue3-project-details.md +0 -547
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# HTML Technical Diagrams
|
|
2
|
+
|
|
3
|
+
Use this route when a technical diagram should be easy to open in a browser, share as one file, switch dark/light themes, and export from the browser after visual QA.
|
|
4
|
+
|
|
5
|
+
This route complements, but does not replace, other diagram sources:
|
|
6
|
+
|
|
7
|
+
| Need | Prefer |
|
|
8
|
+
| ---- | ------ |
|
|
9
|
+
| Small markdown-maintained diagram | Mermaid, Graphviz, or SVG |
|
|
10
|
+
| Editable source for future manual changes | `fec-drawio-studio` and `.drawio` |
|
|
11
|
+
| Browser-ready themed technical diagram | HTML technical diagram route |
|
|
12
|
+
| Raster-first visual, poster, concept art, or image edit | Image generation or editing route |
|
|
13
|
+
|
|
14
|
+
## Supported Diagram Intents
|
|
15
|
+
|
|
16
|
+
- `architecture`: system topology, system blueprints, deployment topology, cloud regions, trust boundaries, clients, gateways, services, data stores, event buses, auth flows, agent runtime maps, memory or recall overview diagrams, before/after architecture comparisons, and infrastructure overview diagrams.
|
|
17
|
+
- `workflow`: ownership lanes, process maps, approval gates, automation runs, exception paths, cyclical loops, runbooks, CI/CD, incident response, tool calls, and request lifecycles.
|
|
18
|
+
- `sequence`: participants over time, API call chains, cache fallback, auth checks, async traces, and return messages.
|
|
19
|
+
- `dataflow`: sources, ingest, processing, storage, consumers, PII boundaries, governance, analytics, and lineage.
|
|
20
|
+
- `lifecycle`: object states, terminal states, retries, waits, cancellation, timeout, deployment or order status transitions.
|
|
21
|
+
|
|
22
|
+
Use the `architecture` mode for browser-ready overview diagrams with explicit coordinates. Use `fec-drawio-studio` instead when the priority is `.drawio` source, official vendor icons, diagrams.net manual editing, or complex auto-layout.
|
|
23
|
+
|
|
24
|
+
## Themed Semantic Diagrams
|
|
25
|
+
|
|
26
|
+
Use `visual.style` when the same JSON source needs a clearer delivery tone without changing its model: `default`, `terminal`, `blueprint`, `minimal`, `glass`, `warm`, `openai`, or `editorial-dark`.
|
|
27
|
+
|
|
28
|
+
For agent, memory, and AI workflow maps, prefer architecture nodes with semantic `type` values:
|
|
29
|
+
|
|
30
|
+
- Actors and entry points: `user`, `browser`, `gateway`.
|
|
31
|
+
- Intelligence and orchestration: `agent`, `model`, `tool`.
|
|
32
|
+
- Memory and knowledge: `memory`, `vectorstore`, `graphdb`, `document`.
|
|
33
|
+
- Runtime movement: `queue`, `messagebus`, `backend`, `external`.
|
|
34
|
+
|
|
35
|
+
Use connection `flow` values when arrows need meaning beyond visual direction:
|
|
36
|
+
|
|
37
|
+
- `control`: orchestration, policy, trigger, or command.
|
|
38
|
+
- `data`: request payloads, documents, embeddings, facts, or responses.
|
|
39
|
+
- `read`: retrieval from memory or stores.
|
|
40
|
+
- `write`: persistence, indexing, notes, or memory updates.
|
|
41
|
+
- `async`: evented or queued work.
|
|
42
|
+
- `feedback`: loops, retries, refinement, or reasoning cycles.
|
|
43
|
+
|
|
44
|
+
When two or more flow types are present, the renderer emits a flow legend automatically. Keep arrow labels short and use `waypoints` to route around dense groups, title labels, and node interiors.
|
|
45
|
+
|
|
46
|
+
## System Blueprint Workflow
|
|
47
|
+
|
|
48
|
+
Use the architecture route for presentation-ready system blueprints, deployment topology, integration maps, agent runtime views, memory or recall maps, and before/after architecture comparisons. First extract a compact system model, then draw:
|
|
49
|
+
|
|
50
|
+
- Entry surfaces: browsers, mobile clients, CLIs, webhooks, schedulers, or agent/session entry points.
|
|
51
|
+
- Application layer: gateways, frontend apps, backend services, workers, orchestration, runtime hosts, and tool adapters.
|
|
52
|
+
- Data layer: databases, object stores, caches, vector stores, queues, event buses, logs, and analytics stores.
|
|
53
|
+
- External dependencies: identity providers, AI models, payment/email services, SaaS APIs, cloud services, design tools, or runtime connectors.
|
|
54
|
+
- Identity and trust boundaries: auth, permissions, PII zones, tenant boundaries, private networks, secret stores, and policy checks.
|
|
55
|
+
- Key flows: request/control flow, data flow, event flow, deployment flow, recall/memory flow, or before/after migration flow.
|
|
56
|
+
|
|
57
|
+
Keep the first blueprint readable:
|
|
58
|
+
|
|
59
|
+
- Show 4-10 primary nodes and collapse low-value files, classes, or endpoints into grouped nodes.
|
|
60
|
+
- Use 1-3 group boundaries for layers, trust zones, runtime environments, or ownership domains.
|
|
61
|
+
- Include a short title and subtitle that work when the file is shared outside the original conversation.
|
|
62
|
+
- Use a legend or up to three summary cards for runtime, data, trust, risks, inputs, or outcomes.
|
|
63
|
+
- Prefer semantic color roles over decorative styling, and split into multiple diagrams when connectors or labels become dense.
|
|
64
|
+
|
|
65
|
+
For README or stakeholder handoff, keep the JSON IR and HTML as the editable source, then export SVG/PNG/JPG artifacts:
|
|
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
|
+
Raster export uses an existing Chromium-family browser when available. If the environment cannot rasterize SVG, deliver the generated HTML/SVG and state that PNG/JPG export needs a local browser.
|
|
73
|
+
|
|
74
|
+
## JSON IR
|
|
75
|
+
|
|
76
|
+
All modes require:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"schema_version": 1,
|
|
81
|
+
"diagram_type": "workflow",
|
|
82
|
+
"meta": {
|
|
83
|
+
"title": "Release Workflow",
|
|
84
|
+
"subtitle": "PR to production"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Mode-specific minimum fields:
|
|
90
|
+
|
|
91
|
+
- `architecture`: `nodes`, `connections`; optional `groups`, `legend`, and `summary`.
|
|
92
|
+
- `workflow`: `lanes`, `nodes`, `edges`; optional `summary`.
|
|
93
|
+
- `sequence`: `participants`, `messages`.
|
|
94
|
+
- `dataflow`: `stages`, `nodes`, `flows`.
|
|
95
|
+
- `lifecycle`: `lanes`, `states`, `transitions`.
|
|
96
|
+
|
|
97
|
+
IDs must start with a letter and use only letters, numbers, `_`, and `-`. Keep labels short enough to read inside nodes; put long explanation in surrounding prose instead of the diagram.
|
|
98
|
+
|
|
99
|
+
## Process Workflow IR
|
|
100
|
+
|
|
101
|
+
Workflow mode is for ordered processes where ownership, decisions, branches, and loop-backs matter more than exact infrastructure topology. Use lanes for actors or systems, nodes for steps, and edges for outcomes. Nodes still support explicit `col` placement so authors can control reading order without relying on a hidden auto-layout engine.
|
|
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 node fields:
|
|
137
|
+
|
|
138
|
+
- `type`: use `start`, `active`, `waiting`, `decision`, `success`, `failure`, or `external` for process semantics.
|
|
139
|
+
- `actor`: optional short owner or system label above the node.
|
|
140
|
+
- `step`: optional displayed step marker. If omitted, workflow nodes receive sequential markers automatically.
|
|
141
|
+
- `sublabel`, `width`, `height`, and `yOffset`: optional readability adjustments for dense lanes.
|
|
142
|
+
|
|
143
|
+
Workflow edge fields:
|
|
144
|
+
|
|
145
|
+
- `variant`: use `emphasis` for happy paths, `return` or `dashed` for loop-backs and rework, and `security` only for trust or policy checks.
|
|
146
|
+
- `waypoints`: optional `[x, y]` points for exception paths, cross-row links, or loops that should avoid labels and nodes.
|
|
147
|
+
|
|
148
|
+
Use `summary` for compact process metadata such as prerequisites, inputs/outputs, or tools. Keep long explanations outside the SVG so labels remain readable.
|
|
149
|
+
|
|
150
|
+
## Architecture IR
|
|
151
|
+
|
|
152
|
+
Architecture mode uses explicit coordinates because system diagrams often need intentional placement, boundaries, and trust zones:
|
|
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
|
+
Supported node and group types include `frontend`, `backend`, `database`, `cloud`, `security`, `messagebus`, `external`, `agent`, `model`, `memory`, `vectorstore`, `graphdb`, `tool`, `document`, `queue`, `browser`, `user`, and `gateway`. Connections support the standard variants `default`, `emphasis`, `security`, `dashed`, and `return`; architecture connections may also include `flow`. Add `waypoints` as `[[x, y], ...]` when a connection needs to route around boundaries or labels.
|
|
186
|
+
|
|
187
|
+
Architecture output includes an automatic legend unless `legend` is set to `false`. A custom legend can be supplied as `{ "label": "...", "type": "..." }` items. `summary` renders up to three cards below the SVG and is not included in the layout manifest, so PNG QA focuses on the diagram itself.
|
|
188
|
+
|
|
189
|
+
## Architecture Layout Rules
|
|
190
|
+
|
|
191
|
+
- Draw groups as broad boundaries around components, not as decorative panels.
|
|
192
|
+
- Keep legends below or outside all boundaries; increase the coordinates and view area rather than squeezing content.
|
|
193
|
+
- Use `messagebus` nodes for event buses and place them in the gap between services.
|
|
194
|
+
- Use `security` connections for auth, token, policy, or trust-boundary flows.
|
|
195
|
+
- Prefer `waypoints` over dense crossing lines when gateways fan out to several services.
|
|
196
|
+
- Split the diagram when the overview needs more than one dense cluster or when label readability depends on shrinking text.
|
|
197
|
+
|
|
198
|
+
## Render Command
|
|
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
|
+
The generated HTML is self-contained and includes:
|
|
209
|
+
|
|
210
|
+
- Inline SVG.
|
|
211
|
+
- CSS-variable dark/light theme.
|
|
212
|
+
- Browser controls for theme toggle, SVG download, and print/PDF.
|
|
213
|
+
- Optional layout manifest for PNG QA.
|
|
214
|
+
|
|
215
|
+
## QA and Repair
|
|
216
|
+
|
|
217
|
+
After exporting a PNG from the browser, run:
|
|
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
|
+
Repair the source JSON or rendering dimensions rather than editing pixels:
|
|
227
|
+
|
|
228
|
+
- Overlap: split dense lanes or add rows/lanes/stages.
|
|
229
|
+
- Truncated label: shorten labels, add `sublabel`, or widen nodes.
|
|
230
|
+
- Connector through label: reduce edge labels or separate nearby nodes.
|
|
231
|
+
- Dense flow: split into overview and detail diagrams.
|
|
232
|
+
- Edge clipping: increase output space or simplify the path.
|
|
233
|
+
|
|
234
|
+
## Delivery Notes
|
|
235
|
+
|
|
236
|
+
Deliver the `.html` source together with any exported SVG/PNG/JPG requested by the user. Report the route used, source file, exported file, QA result, and any naming or domain assumptions that still need human confirmation.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# PNG QA And Autofix
|
|
2
|
+
|
|
3
|
+
## Loop
|
|
4
|
+
|
|
5
|
+
1. Export PNG from the editable source or image workflow.
|
|
6
|
+
2. Inspect the PNG visually.
|
|
7
|
+
3. Run `png-qa.mjs` with a manifest when available.
|
|
8
|
+
4. Convert each issue into source, prompt, or layout changes.
|
|
9
|
+
5. Repeat for 2 rounds by default, up to 5 when the user asks for more repair attempts.
|
|
10
|
+
|
|
11
|
+
## Issue mapping
|
|
12
|
+
|
|
13
|
+
| Issue | Repair |
|
|
14
|
+
| ----- | ------ |
|
|
15
|
+
| `blank-image` | Check export target, renderer errors, hidden layers, transparent fill, or failed image generation. |
|
|
16
|
+
| `edge-clipping` | Add canvas padding, expand SVG viewBox, reduce subject scale, or export a larger frame. |
|
|
17
|
+
| `box-overlap` | Increase spacing, reflow to grid/layers, split clusters, or shorten labels. |
|
|
18
|
+
| `box-out-of-bounds` | Move the node inside canvas or increase canvas dimensions. |
|
|
19
|
+
| `label-overflow` | Wrap text, widen the box, reduce copy, or increase font/container size together. |
|
|
20
|
+
| `connector-through-label` | Add waypoints around boxes, move labels, or use orthogonal routing. |
|
|
21
|
+
| `connector-stacking` | Offset parallel connectors or replace repeated lines with a labeled grouped path. |
|
|
22
|
+
| `manifest-canvas-mismatch` | Regenerate the manifest from final export dimensions. |
|
|
23
|
+
|
|
24
|
+
## Manifest quality
|
|
25
|
+
|
|
26
|
+
The helper can only reason about overlaps and connectors when the manifest coordinates match the exported PNG. If the manifest is stale, repair the manifest first, then rerun QA.
|
|
27
|
+
|
|
28
|
+
## Reporting
|
|
29
|
+
|
|
30
|
+
Report the number of QA rounds and the final issue list. If issues remain because the source renderer cannot expose layout coordinates, say which checks were image-only and which require manual visual review.
|
|
@@ -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
|
+
}
|