@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import m from"node:fs";import d from"node:path";import
|
|
3
|
-
`,"utf8")}function
|
|
4
|
-
description = "${(u=>u.replace(/\\/g,"\\\\").replace(/"/g,'\\"'))(
|
|
2
|
+
import m from"node:fs";import d from"node:path";import At from"node:readline";import S from"node:path";import K from"node:fs";import k from"node:fs";import v from"node:path";import Zn from"node:crypto";import et from"node:os";var H;function Ke({baseDir:e,cwd:n=process.cwd(),mode:t,packageVersion:o,runtime:i,isGlobal:r,language:s}){let l=v.join(e,"frontend-craft.manifest.json");H={baseDir:v.resolve(e),cwd:v.resolve(n),homeDir:v.resolve(et.homedir()),mode:t,packageVersion:o,runtime:i,scope:r?"global":"local",language:s,manifestPath:l,previousFiles:nt(l),writtenFiles:new Map,skippedFiles:new Set}}function Je(){let e=H;if(H=void 0,!e)return;for(let[o,i]of e.previousFiles)e.skippedFiles.has(o)&&!e.writtenFiles.has(o)&&e.writtenFiles.set(o,i);let n=[...e.writtenFiles.entries()].map(([o,i])=>en(o,i)).sort((o,i)=>o.path.localeCompare(i.path)),t={packageVersion:e.packageVersion,runtime:e.runtime,scope:e.scope,language:e.language,installedAt:new Date().toISOString(),files:n};f(v.dirname(e.manifestPath)),k.writeFileSync(e.manifestPath,`${JSON.stringify(t,null,2)}
|
|
3
|
+
`,"utf8")}function Ye(){H=void 0}function re(e){return v.join(e,"frontend-craft.manifest.json")}function le(e){if(k.existsSync(e))try{let n=JSON.parse(k.readFileSync(e,"utf8"));return{...n,files:(n.files??[]).map(t=>({...t,path:Ne(t.path)}))}}catch{return}}function nt(e){let n=le(e);return new Map((n?.files??[]).map(t=>[Ze(t.root??"baseDir",Ne(t.path)),t.hash]))}function Qe(e){return Zn.createHash("sha256").update(e).digest("hex")}function $e(e){return Qe(k.readFileSync(e))}function Xe(e){let n=H;if(!n)return;let t=v.resolve(e),o=[["baseDir",n.baseDir],["cwd",n.cwd],["home",n.homeDir]];for(let[i,r]of o){let s=v.relative(r,t);if(s&&!s.startsWith("..")&&!v.isAbsolute(s))return Ze(i,Ne(s))}}function Ne(e){return e.split(v.sep).join("/")}function Ze(e,n){return`${e}:${n}`}function en(e,n){let t=/^(baseDir|cwd|home):(.*)$/.exec(e);if(!t)return{path:e,hash:n};let o=t[1];return{...o==="baseDir"?{}:{root:o},path:t[2],hash:n}}function nn(e){let n=H,t=Xe(e);if(!n||!t||n.mode!=="update"||!k.existsSync(e))return!1;let o=n.previousFiles.get(t);return!o||$e(e)===o?!1:(n.skippedFiles.add(t),console.log(`Skipped modified file: ${en(t,o).path}`),!0)}function tn(e,n){let t=H,o=Xe(e);!t||!o||t.writtenFiles.set(o,Qe(n))}function f(e){k.existsSync(e)||k.mkdirSync(e,{recursive:!0})}function D(e,n){if(nn(n))return;f(v.dirname(n));let t=k.readFileSync(e);k.copyFileSync(e,n),tn(n,t)}function p(e,n,t={}){if(k.existsSync(e)){f(n);for(let o of k.readdirSync(e)){let i=v.join(e,o),r=o;if(t.filter&&!t.filter(r))continue;let s=v.join(n,o);k.statSync(i).isDirectory()?p(i,s,t):D(i,s)}}}function C(e){return k.readFileSync(e,"utf8")}function y(e,n){nn(e)||(f(v.dirname(e)),k.writeFileSync(e,n,"utf8"),tn(e,n))}function tt(e,n){let t=S.resolve(e);return n.replaceAll("${CLAUDE_PLUGIN_ROOT}",t).replaceAll("${FRONTEND_CRAFT_ROOT}",t)}function ot(e){let n=S.join(e,"hooks","hooks.json"),t=C(n);return tt(e,t)}async function on(e){let{pluginRoot:n,contentRoot:t,baseDir:o,dryRun:i,cwd:r,isGlobal:s}=e;if(i){console.log(`[dry-run] would install Claude Code files into ${o}`);return}f(o),p(S.join(t,"skills"),S.join(o,"skills")),p(S.join(t,"agents"),S.join(o,"agents")),p(S.join(t,"commands"),S.join(o,"commands")),s||p(S.join(t,"templates","shared","rules"),S.join(o,"rules"));let l=S.join(t,"templates","claude");if(K.existsSync(l))for(let c of K.readdirSync(l)){let u=S.join(o,c);K.existsSync(u)||D(S.join(l,c),u)}if(y(S.join(o,"hooks.json"),ot(n)),!s&&K.existsSync(S.join(n,".mcp.json"))){let c=S.join(r,".mcp.json");K.existsSync(c)||D(S.join(n,".mcp.json"),c)}let a=S.join(n,".claude-plugin","plugin.json");if(!s&&K.existsSync(a)){f(S.join(r,".claude-plugin")),D(a,S.join(r,".claude-plugin","plugin.json"));let c=S.join(n,".claude-plugin","marketplace.json");K.existsSync(c)&&D(c,S.join(r,".claude-plugin","marketplace.json"))}}import $ from"node:path";import ae from"node:fs";import st from"node:os";function sn(e,n){let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);if(!t)throw new Error(`no frontmatter: ${n}`);let o=t[1],i=t[2].trim().replace(/\.claude\/rules/g,".codex/rules").replace(/\bCLAUDE\.md\b/g,"AGENTS.md"),r=o.match(/^name:\s*(.+)$/m);if(!r)throw new Error(`no name in frontmatter: ${n}`);let s=r[1].trim(),l=o.match(/^description:\s*(.+)$/m),a=l?l[1].trim():"";return`name = "${s}"
|
|
4
|
+
description = "${(u=>u.replace(/\\/g,"\\\\").replace(/"/g,'\\"'))(a)}"
|
|
5
5
|
|
|
6
6
|
model = "gpt-5.4"
|
|
7
7
|
model_reasoning_effort = "high"
|
|
@@ -9,43 +9,44 @@ model_reasoning_effort = "high"
|
|
|
9
9
|
developer_instructions = """
|
|
10
10
|
`+i+`
|
|
11
11
|
"""
|
|
12
|
-
`}async function
|
|
12
|
+
`}async function rn(e){let{contentRoot:n,baseDir:t,cwd:o,dryRun:i,isGlobal:r}=e,s=$.join(n,"agents"),l=$.join(t,"agents"),a=$.join(t,"rules"),c=r?$.join(st.homedir(),".agents","skills"):$.join(o,".agents","skills");if(i){console.log(`[dry-run] codex: ${t}, agents -> ${l}, skills -> ${c}`);return}f(l),f(c);for(let j of ae.readdirSync(s)){if(!j.endsWith(".md"))continue;let R=C($.join(s,j)),M=sn(R,j);y($.join(l,j.replace(/\.md$/,".toml")),M)}p($.join(n,"skills"),c);let u=$.join(n,"templates","shared","rules");!r&&ae.existsSync(u)&&p(u,a);let g=$.join(n,"templates","codex","AGENTS.md"),b=$.join(n,"templates","codex","config.toml");if(!r&&ae.existsSync(g)){let j=$.join(o,"AGENTS.md");ae.existsSync(j)||D(g,j)}ae.existsSync(b)&&D(b,$.join(t,"config.toml"))}import Z from"node:path";import ln from"node:fs";async function an(e){let{contentRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o){console.log(`[dry-run] cursor -> ${t}`);return}f(t);let r=Z.join(t,"skills");p(Z.join(n,"skills"),r);let s=Z.join(n,"templates","shared","rules"),l=Z.join(t,"rules");if(!i&&ln.existsSync(s)){f(l);for(let a of ln.readdirSync(s)){if(!a.endsWith(".md"))continue;let c=C(Z.join(s,a)),u=a.replace(/\.md$/,""),g=`---
|
|
13
13
|
description: Frontend Craft - ${u}
|
|
14
14
|
globs: "**/*.{ts,tsx,vue,js,jsx,css,scss,less,html}"
|
|
15
15
|
---
|
|
16
16
|
|
|
17
17
|
`+c+`
|
|
18
|
-
`;y(
|
|
18
|
+
`;y(Z.join(l,`${u}.mdc`),g)}}}import E from"node:path";import Oe from"node:fs";async function cn(e){let{contentRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o){console.log(`[dry-run] windsurf -> ${t}`);return}f(t);let r=E.join(t,"workflows"),s=E.join(t,"rules");f(r);let l=E.join(n,"commands");for(let c of Oe.readdirSync(l)){if(!c.endsWith(".md"))continue;let u=C(E.join(l,c));y(E.join(r,c),u)}let a=E.join(n,"templates","shared","rules");if(!i&&Oe.existsSync(a)){f(s);for(let c of Oe.readdirSync(a)){if(!c.endsWith(".md"))continue;let u=C(E.join(a,c));y(E.join(s,c),u)}}p(E.join(n,"skills"),E.join(t,"skills"))}import L from"node:path";import ce from"node:fs";async function ge(e){let{contentRoot:n,baseDir:t,dryRun:o}=e,i=L.join(t,"command");if(o){console.log(`[dry-run] opencode/kilo commands -> ${i}`);return}f(i);let r=L.join(n,"commands");for(let c of ce.readdirSync(r)){if(!c.endsWith(".md"))continue;let u=C(L.join(r,c));y(L.join(i,c),u)}let s=L.join(t,"skills");f(s);let l=L.join(n,"skills");for(let c of ce.readdirSync(l)){let u=L.join(l,c);if(!ce.statSync(u).isDirectory())continue;let g=L.join(u,"SKILL.md");if(ce.existsSync(g)){let b=L.join(s,c);p(u,b)}}let a=L.join(t,"opencode.jsonc");e.runtime==="opencode"&&!ce.existsSync(a)&&y(a,`{
|
|
19
19
|
"$schema": "https://opencode.ai/config.json",
|
|
20
20
|
"permissions": { "bash": "allow" }
|
|
21
21
|
}
|
|
22
|
-
`)}async function
|
|
23
|
-
`];if(
|
|
22
|
+
`)}async function un(e){return ge(e)}async function fn(e){return ge(e)}import ue from"node:path";import dn from"node:fs";async function pn(e){let{contentRoot:n,baseDir:t,cwd:o,dryRun:i,isGlobal:r}=e;if(i){console.log(`[dry-run] gemini -> ${t}`);return}f(t);let s=ue.join(t,"extensions","frontend-craft");f(s),p(ue.join(n,"skills"),ue.join(s,"skills"));let l=ue.join(n,"templates","claude","CLAUDE.md"),a=ue.join(o,"GEMINI.md");if(!r&&!dn.existsSync(a)&&dn.existsSync(l)){let c=C(l).replaceAll(".claude/",".gemini/").replaceAll("CLAUDE.md","GEMINI.md");y(a,c)}}import W from"node:path";import Fe from"node:fs";async function mn(e){let{contentRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o){console.log(`[dry-run] copilot -> ${t}`);return}f(t);let r=W.join(t,"instructions"),s=W.join(t,"prompts");if(f(s),!i){f(r);let a=W.join(n,"templates","shared","rules"),c=[`# Frontend Craft - Copilot instructions
|
|
23
|
+
`];if(Fe.existsSync(a))for(let u of Fe.readdirSync(a))u.endsWith(".md")&&c.push(`
|
|
24
24
|
## ${u}
|
|
25
25
|
|
|
26
|
-
`,C(
|
|
27
|
-
`];if(
|
|
28
|
-
## ${l}
|
|
29
|
-
|
|
30
|
-
`,C(ue.join(s,l)));y(ue.join(r,"frontend-craft.md"),a.join(""))}import fe from"node:path";import fn from"node:fs";async function dn(e){let{pluginRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o)return console.log(`[dry-run] cline -> ${fe.join(t,".clinerules")}`);if(i)return;let r=fe.join(n,"templates","shared","rules"),s=[`# Frontend Craft - Cline rules
|
|
31
|
-
`];if(fn.existsSync(r))for(let a of fn.readdirSync(r))a.endsWith(".md")&&s.push(`
|
|
26
|
+
`,C(W.join(a,u)));y(W.join(r,"frontend-craft.instructions.md"),c.join(""))}let l=W.join(n,"commands");for(let a of Fe.readdirSync(l))a.endsWith(".md")&&y(W.join(s,a),C(W.join(l,a)))}import ee from"node:path";async function gn(e){let{contentRoot:n,baseDir:t,dryRun:o}=e;if(o)return console.log(`[dry-run] antigravity -> ${t}`);f(t),p(ee.join(n,"skills"),ee.join(t,"skills"))}async function hn(e){let{contentRoot:n,baseDir:t,dryRun:o}=e;if(o)return console.log(`[dry-run] augment -> ${t}`);f(t),p(ee.join(n,"skills"),ee.join(t,"skills"))}async function yn(e){let{contentRoot:n,baseDir:t,dryRun:o}=e;if(o)return console.log(`[dry-run] codebuddy -> ${t}`);f(t),p(ee.join(n,"skills"),ee.join(t,"skills"))}import he from"node:path";import Cn from"node:fs";async function Sn(e){let{contentRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o)return console.log(`[dry-run] trae -> ${t}`);if(i)return;let r=he.join(t,"rules");f(r);let s=he.join(n,"templates","shared","rules"),l=[`# Frontend Craft - Trae rules bundle
|
|
27
|
+
`];if(Cn.existsSync(s))for(let a of Cn.readdirSync(s))a.endsWith(".md")&&l.push(`
|
|
32
28
|
## ${a}
|
|
33
29
|
|
|
34
|
-
`,C(
|
|
35
|
-
`
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
`,C(he.join(s,a)));y(he.join(r,"frontend-craft.md"),l.join(""))}import ye from"node:path";import jn from"node:fs";async function xn(e){let{contentRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o)return console.log(`[dry-run] cline -> ${ye.join(t,".clinerules")}`);if(i)return;let r=ye.join(n,"templates","shared","rules"),s=[`# Frontend Craft - Cline rules
|
|
31
|
+
`];if(jn.existsSync(r))for(let l of jn.readdirSync(r))l.endsWith(".md")&&s.push(`
|
|
32
|
+
## ${l}
|
|
33
|
+
|
|
34
|
+
`,C(ye.join(r,l)));y(ye.join(t,".clinerules"),s.join(""))}import J from"node:path";import Me from"node:fs";async function In(e){let{contentRoot:n,baseDir:t,cwd:o,dryRun:i}=e;if(i)return console.log(`[dry-run] openclaw -> ${t}`);f(t),p(J.join(n,"skills"),J.join(t,"skills")),p(J.join(n,"commands"),J.join(t,"commands"));let r=J.join(n,"templates","openclaw");if(Me.existsSync(r))for(let s of Me.readdirSync(r)){if(!s.endsWith(".md"))continue;let l=J.join(o,s);Me.existsSync(l)||D(J.join(r,s),l)}}import N from"node:path";import bn from"node:fs";var it=["fec-security-check.js","fec-format-changed-file.js","fec-run-tests.js","fec-notify.js"];async function vn(e){let{pluginRoot:n,contentRoot:t,baseDir:o,dryRun:i,isGlobal:r}=e;if(i){console.log(`[dry-run] qoder -> ${o}`);return}f(o),p(N.join(t,"skills"),N.join(o,"skills")),p(N.join(t,"commands"),N.join(o,"commands")),p(N.join(t,"agents"),N.join(o,"agents")),r||p(N.join(t,"templates","shared","rules"),N.join(o,"rules")),rt(n,N.join(o,"hooks")),y(N.join(o,"settings.json"),JSON.stringify(lt(o),null,2)+`
|
|
35
|
+
`)}function rt(e,n){f(n);for(let t of it){let o=N.join(e,"dist","hooks",t);if(!bn.existsSync(o))throw new Error(`Missing built hook script: ${o}. Run "npm run build" before installing.`);D(o,N.join(n,t))}}function lt(e){let n=N.join(e,"settings.json"),t=at(n);return{...t,hooks:{...ne(t.hooks),PreToolUse:[...Se(ne(t.hooks).PreToolUse),Ce("Bash|Shell",".qoder/hooks/fec-security-check.js","Checking command safety...")],PostToolUse:[...Se(ne(t.hooks).PostToolUse),Ce("Write|Edit|MultiEdit",".qoder/hooks/fec-format-changed-file.js","Running formatter...")],Stop:[...Se(ne(t.hooks).Stop),Ce(".*",".qoder/hooks/fec-run-tests.js","Running final validation...")],Notification:[...Se(ne(t.hooks).Notification),Ce(".*",".qoder/hooks/fec-notify.js")]}}}function at(e){if(!bn.existsSync(e))return{};try{let n=JSON.parse(C(e));return ne(n)}catch{return{}}}function Ce(e,n,t){return{matcher:e,hooks:[{type:"command",command:`node "${n}"`,...t?{statusMessage:t}:{}}]}}function ne(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)?e:{}}function Se(e){return Array.isArray(e)?e:[]}var F=["claude","codex","cursor","windsurf","opencode","kilo","gemini","copilot","antigravity","augment","trae","codebuddy","cline","openclaw","qoder"],je={claude:on,codex:rn,cursor:an,windsurf:cn,opencode:un,kilo:fn,gemini:pn,copilot:mn,antigravity:gn,augment:hn,trae:Sn,codebuddy:yn,cline:xn,openclaw:In,qoder:vn};import ct from"node:fs";import ut from"node:os";import ft from"node:path";import Ie from"node:readline";import kn from"node:os";import x from"node:path";function I(e){return e&&(e.startsWith("~/")||e==="~"?x.join(kn.homedir(),e.slice(1)):e)}function xe(e){let n=kn.homedir(),t=process.env;switch(e){case"claude":return t.CLAUDE_CONFIG_DIR?I(t.CLAUDE_CONFIG_DIR):x.join(n,".claude");case"cursor":return t.CURSOR_CONFIG_DIR?I(t.CURSOR_CONFIG_DIR):x.join(n,".cursor");case"gemini":return t.GEMINI_CONFIG_DIR?I(t.GEMINI_CONFIG_DIR):x.join(n,".gemini");case"codex":return t.CODEX_HOME?I(t.CODEX_HOME):x.join(n,".codex");case"copilot":return t.COPILOT_CONFIG_DIR?I(t.COPILOT_CONFIG_DIR):x.join(n,".copilot");case"antigravity":return t.ANTIGRAVITY_CONFIG_DIR?I(t.ANTIGRAVITY_CONFIG_DIR):x.join(n,".gemini","antigravity");case"windsurf":return t.WINDSURF_CONFIG_DIR?I(t.WINDSURF_CONFIG_DIR):x.join(n,".codeium","windsurf");case"augment":return t.AUGMENT_CONFIG_DIR?I(t.AUGMENT_CONFIG_DIR):x.join(n,".augment");case"trae":return t.TRAE_CONFIG_DIR?I(t.TRAE_CONFIG_DIR):x.join(n,".trae");case"codebuddy":return t.CODEBUDDY_CONFIG_DIR?I(t.CODEBUDDY_CONFIG_DIR):x.join(n,".codebuddy");case"cline":return t.CLINE_CONFIG_DIR?I(t.CLINE_CONFIG_DIR):x.join(n,".cline");case"opencode":return t.OPENCODE_CONFIG_DIR?I(t.OPENCODE_CONFIG_DIR):t.XDG_CONFIG_HOME?x.join(I(t.XDG_CONFIG_HOME),"opencode"):x.join(n,".config","opencode");case"kilo":return t.KILO_CONFIG_DIR?I(t.KILO_CONFIG_DIR):t.XDG_CONFIG_HOME?x.join(I(t.XDG_CONFIG_HOME),"kilo"):x.join(n,".config","kilo");case"openclaw":return t.OPENCLAW_CONFIG_DIR?I(t.OPENCLAW_CONFIG_DIR):x.join(n,".openclaw");case"qoder":return t.QODER_CONFIG_DIR?I(t.QODER_CONFIG_DIR):x.join(n,".qoder");default:return t.CLAUDE_CONFIG_DIR?I(t.CLAUDE_CONFIG_DIR):x.join(n,".claude")}}var _e={claude:".claude",codex:".codex",cursor:".cursor",windsurf:".windsurf",opencode:".opencode",kilo:".kilo",gemini:".gemini",copilot:".github",antigravity:".agent",augment:".augment",trae:".trae",codebuddy:".codebuddy",cline:"",openclaw:".openclaw",qoder:".qoder"};function Y({runtime:e,isGlobal:n,cwd:t}){if(n)return xe(e);if(e==="cline")return t;let o=_e[e]??".claude";return x.join(t,o)}var dt={claude:"Claude Code",codex:"Codex",cursor:"Cursor",windsurf:"Windsurf",opencode:"OpenCode",kilo:"Kilo",gemini:"Gemini",copilot:"Copilot",antigravity:"Antigravity",augment:"Augment",trae:"Trae",codebuddy:"CodeBuddy",cline:"Cline",openclaw:"OpenClaw",qoder:"Qoder"};function Rn(e){let n=ut.homedir();return e===n?"~":e.startsWith(`${n}${ft.sep}`)?`~${e.slice(n.length)}`:e}function pt(e){let n=_e[e];return n?`./${n}`:"./"}var be=F.map((e,n)=>({choice:String(n+1),runtime:e,label:dt[e]??e})),mt=String(be.length+1);function wn(e){return e.filter((n,t)=>e.indexOf(n)===t)}function gt(e,n,t){return Math.max(n,Math.min(t,e))}function ht(e){return!e||e.ctrl||e.meta?"":typeof e.sequence=="string"&&e.sequence.length===1&&e.sequence>=" "?e.sequence:typeof e.name=="string"&&e.name.length===1?e.name:""}function yt(){return be.map(e=>{let n=Rn(xe(e.runtime));return{value:e.runtime,label:e.label,description:n,selectedSuffix:"selected"}})}function Ct(e){let n=wn(e.map(o=>Rn(xe(o)))).join(", "),t=wn(e.map(o=>pt(o))).join(", ");return[{value:"global",label:"Global",description:`${n} - available in all projects`,selectedSuffix:"selected"},{value:"local",label:"Local",description:`${t} - this project only`,selectedSuffix:"selected"}]}function St(){return[{value:"en",label:"English",description:"canonical default content",selectedSuffix:"selected"},{value:"zh-CN",label:"简体中文",description:"localized AI-facing content",selectedSuffix:"已选择"}]}function Pe({message:e,options:n,selected:t=[],multiple:o=!0,pageSize:i=15,validate:r=l=>l.length>0,transform:s=(l=>l)}){return{message:e,options:n,selected:t.filter((a,c)=>t.indexOf(a)===c),multiple:o,pageSize:i,search:"",cursor:0,error:"",visibleOptions(){let a=this.search.trim().toLowerCase();return a?this.options.filter(c=>c.label.toLowerCase().includes(a)||c.value.toLowerCase().includes(a)):this.options},move(a){let c=this.visibleOptions();this.cursor=gt(this.cursor+a,0,Math.max(0,c.length-1)),this.error=""},toggle(){let a=this.visibleOptions()[this.cursor];a&&(this.multiple?this.selected.includes(a.value)?this.selected=this.selected.filter(c=>c!==a.value):this.selected=[...this.selected,a.value]:this.selected=[a.value],this.error="")},backspace(){this.search.length>0?(this.search=this.search.slice(0,-1),this.cursor=0):this.selected.length>0&&(this.selected=this.selected.slice(0,-1)),this.error=""},type(a){this.search+=a,this.cursor=0,this.error=""},confirm(){let a=r(this.selected);if(a!==!0){this.error=typeof a=="string"?a:"Select at least one option";return}return s(this.selected)}}}function Dn(e={}){return Pe({message:`Which runtime(s) would you like to install for? (${be.length} available)`,options:yt(),selected:["claude"],multiple:!0,pageSize:e.pageSize??15,transform:n=>n})}function $n(e,n={}){return Pe({message:"Where would you like to install?",options:Ct(e),selected:["global"],multiple:!1,pageSize:n.pageSize??15,transform:t=>t[0]!=="local"})}function Nn(e={}){return Pe({message:"Which language should frontend-craft install?",options:St(),selected:["en"],multiple:!1,pageSize:e.pageSize??15,transform:n=>n[0]==="zh-CN"?"zh-CN":"en"})}function fe(e){let n=e.visibleOptions(),t=new Set(e.selected),o=new Map(e.options.map(s=>[s.value,s])),i=e.selected.length?e.selected.map(s=>o.get(s)?.label??s).join(", "):"(none selected)",r=[`? ${e.message}`,` Selected: ${i}`,` Search: [${e.search||"type to filter"}]`," Up/Down navigate - Space toggle - Backspace remove - Enter confirm"];if(n.length===0)r.push(" No matches");else{let s=Math.max(0,Math.min(e.cursor-Math.floor(e.pageSize/2),n.length-e.pageSize)),l=Math.min(s+e.pageSize,n.length),a=n.slice(s,l);for(let c=0;c<a.length;c++){let u=a[c],b=s+c===e.cursor,j=t.has(u.value),R=b?">":" ",M=j?"[x]":"[ ]",pe=u.description?` (${u.description})`:"",A=j?` (${u.selectedSuffix??"selected"})`:pe;r.push(` ${R} ${M} ${u.label}${A}`)}if(n.length>e.pageSize){let c=Math.floor(e.cursor/e.pageSize)+1,u=Math.ceil(n.length/e.pageSize);r.push(` (${c}/${u})`)}}return e.error&&r.push(` ${e.error}`),r.join(`
|
|
36
|
+
`)}function jt(){return fe(Dn())}function xt(e){let t=((e==null?"":String(e)).trim()||"1").split(/[\s,]+/).filter(Boolean);if(t.includes(mt))return F.slice();let o=[],i=new Set,r=new Map(be.map(s=>[s.choice,s.runtime]));for(let s of t){let l=r.get(s);!l||i.has(l)||(i.add(l),o.push(l))}return o.length?o:["claude"]}function It(e){return fe($n(e))}function bt(e){return((e==null?"":String(e)).trim()||"1")!=="2"}function vt(){return fe(Nn())}function kt(e){let n=(e==null?"":String(e)).trim()||"1";return n==="2"||n==="zh-CN"?"zh-CN":"en"}var Te;function On(e){return process.stdout.write(e),Te||(Te=ct.readFileSync(0,"utf8").split(/\r?\n/)),Te.shift()??""}function Ee(e){return process.env.FRONTEND_CRAFT_FORCE_INTERACTIVE==="1"&&!process.stdin.isTTY?Promise.resolve(On(e)):new Promise(n=>{let t=Ie.createInterface({input:process.stdin,output:process.stdout});t.question(e,o=>{t.close(),n(o)}),t.on("close",()=>n(""))})}async function Le(e){return process.env.FRONTEND_CRAFT_FORCE_INTERACTIVE==="1"&&!process.stdin.isTTY?On(`${fe(e)}
|
|
37
|
+
`):new Promise(n=>{let t=process.stdin,o=process.stdout,i=t.isRaw,r=0;function s(){r>0&&(Ie.moveCursor(o,0,-r),Ie.clearScreenDown(o));let c=fe(e);o.write(c),o.write(`
|
|
38
38
|
`),r=c.split(`
|
|
39
|
-
`).length}function
|
|
40
|
-
`),process.exitCode=130,n(void 0);return}if(u?.name==="return"||u?.name==="enter"){let g=e.confirm();s(),g!==void 0&&(
|
|
41
|
-
`),
|
|
42
|
-
`),
|
|
43
|
-
`)
|
|
39
|
+
`).length}function l(){t.off("keypress",a),t.isTTY&&t.setRawMode(!!i),t.pause()}function a(c,u){if(u?.ctrl&&u.name==="c"){l(),o.write(`
|
|
40
|
+
`),process.exitCode=130,n(void 0);return}if(u?.name==="return"||u?.name==="enter"){let g=e.confirm();s(),g!==void 0&&(l(),n(g));return}if(u?.name==="up")e.move(-1);else if(u?.name==="down")e.move(1);else if(u?.name==="space")e.toggle();else if(u?.name==="backspace")e.backspace();else{let g=ht(u);g&&e.type(g)}s()}Ie.emitKeypressEvents(t),t.isTTY&&t.setRawMode(!0),t.resume(),t.on("keypress",a),s()})}async function Fn(){if(process.stdin.isTTY){let e=await Le(Dn());return Array.isArray(e)?e:["claude"]}return console.log(`${jt()}
|
|
41
|
+
`),xt(await Ee("Choice [1]: "))}async function Mn(e){if(process.stdin.isTTY){let n=await Le($n(e));return typeof n=="boolean"?n:!0}return console.log(`${It(e)}
|
|
42
|
+
`),bt(await Ee("Choice [1]: "))}async function _n(){return process.stdin.isTTY?await Le(Nn())==="zh-CN"?"zh-CN":"en":(console.log(`${vt()}
|
|
43
|
+
`),kt(await Ee("Choice [1]: ")))}import wt from"node:fs";import Rt from"node:path";var Q="en",ve=["en","zh-CN"];function Ae(e){return ve.includes(e)}function Dt(e){if(e!=null)return Ae(e)?e:void 0}function Tn(e){return Dt(e)??Q}function Pn(e,n){if(n===Q)return e;let t=Rt.join(e,"localized",n);if(!wt.existsSync(t))throw new Error(`Missing localized content pack for language "${n}": ${t}`);return t}var ke={claude:{tier:"full",skills:!0,agents:!0,commands:!0,hooks:!0,rules:!0,templates:!0,mcp:!0,reports:!0,init:"native"},codex:{tier:"full",skills:!0,agents:!0,commands:!1,hooks:!1,rules:!0,templates:!0,mcp:!1,reports:!0,init:"native"},openclaw:{tier:"full",skills:!0,agents:!1,commands:!0,hooks:!1,rules:!1,templates:!0,mcp:!1,reports:!0,init:"native"},qoder:{tier:"full",skills:!0,agents:!0,commands:!0,hooks:!0,rules:!0,templates:!0,mcp:!1,reports:!0,init:"native"},opencode:{tier:"medium",skills:!0,agents:!1,commands:!0,hooks:!1,rules:!1,templates:!0,mcp:!1,reports:!0,init:"rules"},kilo:{tier:"medium",skills:!0,agents:!1,commands:!0,hooks:!1,rules:!1,templates:!1,mcp:!1,reports:!0,init:"rules"},cursor:{tier:"medium",skills:!0,agents:!1,commands:!1,hooks:!1,rules:!0,templates:!1,mcp:!1,reports:!0,init:"rules"},windsurf:{tier:"medium",skills:!0,agents:!1,commands:!0,hooks:!1,rules:!0,templates:!1,mcp:!1,reports:!0,init:"rules"},gemini:{tier:"medium",skills:!0,agents:!1,commands:!1,hooks:!1,rules:!1,templates:!0,mcp:!1,reports:!0,init:"rules"},copilot:{tier:"medium",skills:!1,agents:!1,commands:!0,hooks:!1,rules:!0,templates:!1,mcp:!1,reports:!0,init:"rules"},antigravity:{tier:"skills-rules-only",skills:!0,agents:!1,commands:!1,hooks:!1,rules:!1,templates:!1,mcp:!1,reports:!0,init:"none"},augment:{tier:"skills-rules-only",skills:!0,agents:!1,commands:!1,hooks:!1,rules:!1,templates:!1,mcp:!1,reports:!0,init:"none"},trae:{tier:"skills-rules-only",skills:!1,agents:!1,commands:!1,hooks:!1,rules:!0,templates:!1,mcp:!1,reports:!0,init:"none"},codebuddy:{tier:"skills-rules-only",skills:!0,agents:!1,commands:!1,hooks:!1,rules:!1,templates:!1,mcp:!1,reports:!0,init:"none"},cline:{tier:"skills-rules-only",skills:!1,agents:!1,commands:!1,hooks:!1,rules:!0,templates:!1,mcp:!1,reports:!0,init:"none"}};function En(e){let n=["Runtime","Tier","Skills","Agents","Commands","Hooks","Rules","Templates","MCP","Reports","Init"],t=e.map(r=>{let s=ke[r];if(!s)throw new Error(`Missing capability declaration for runtime: ${r}`);return[r,s.tier,z(s.skills),z(s.agents),z(s.commands),z(s.hooks),z(s.rules),z(s.templates),z(s.mcp),z(s.reports),s.init]}),o=n.map((r,s)=>Math.max(r.length,...t.map(l=>l[s].length))),i=r=>r.map((s,l)=>s.padEnd(o[l])).join(" ").trimEnd();return[i(n),...t.map(i)].join(`
|
|
44
|
+
`)}function z(e){return e?"yes":"no"}import Ln from"node:fs";import te from"node:path";import{fileURLToPath as An}from"node:url";function Gn(e=import.meta.url){let n=te.dirname(An(e));for(;;){if(Ln.existsSync(te.join(n,"package.json"))&&Ln.existsSync(te.join(n,"skills")))return n;let t=te.dirname(n);if(t===n)return te.resolve(te.dirname(An(e)),"../..");n=t}}import oe from"node:fs";import Un from"node:os";import P from"node:path";function we({cwd:e,runtimes:n=F,scopes:t=["local","global"]}){let o=[],i=new Set;for(let r of n)for(let s of t){let l=Y({runtime:r,isGlobal:s==="global",cwd:e}),a=re(l),c=P.resolve(a);if(i.has(c))continue;i.add(c);let u=le(a);u&&(u.runtime!==r||u.scope!==s||o.push({runtime:r,scope:s,baseDir:l,manifestPath:a,manifest:u}))}return o}function Ge({install:e,cwd:n,dryRun:t,force:o}){let i={removed:[],skipped:[],missing:[]},r=new Set;for(let s of e.manifest.files){let l=$t({filePath:s.path,root:s.root??"baseDir",baseDir:e.baseDir,cwd:n});if(!l)continue;if(!oe.existsSync(l)){i.missing.push(s.path);continue}let a=$e(l)!==s.hash;if(a&&!o){i.skipped.push(s.path);continue}i.removed.push({path:s.path,modified:a}),r.add(P.dirname(l)),t||oe.rmSync(l,{force:!0})}return!t&&i.skipped.length===0&&(oe.rmSync(e.manifestPath,{force:!0}),Nt([...r],[e.baseDir,n,Un.homedir()])),i}function $t({filePath:e,root:n,baseDir:t,cwd:o}){let i=n==="baseDir"?t:n==="cwd"?o:Un.homedir(),r=P.resolve(i),s=P.resolve(r,e),l=P.relative(r,s);if(!(l.startsWith("..")||P.isAbsolute(l)))return s}function Nt(e,n){let t=n.map(o=>P.resolve(o));for(let o of e.sort((i,r)=>r.length-i.length)){let i=P.resolve(o);for(;Ot(i,t)&&!t.includes(i)&&!(!oe.existsSync(i)||oe.readdirSync(i).length>0);)oe.rmdirSync(i),i=P.dirname(i)}}function Ot(e,n){return n.some(t=>{let o=P.relative(t,e);return o!==""&&!o.startsWith("..")&&!P.isAbsolute(o)})}import O from"node:fs";import Ue from"node:os";import w from"node:path";function We({claudeConfigDir:e=Ve(),currentVersion:n}){let t=w.join(e,"plugins","cache","frontend-craft","frontend-craft"),o=Mt(e),i=Ft({cacheDir:t,currentInstallPaths:o.paths,currentVersion:n}),r=o.warning,s=!r&&o.paths.length>0;return{claudeConfigDir:e,cacheDir:t,currentInstallPaths:o.paths,entries:i.map(l=>({...l,shouldDelete:s&&l.shouldDelete,reasons:s?l.reasons:["metadata unavailable"]})),canDelete:s,warning:r}}function qn({claudeConfigDir:e=Ve(),currentVersion:n,dryRun:t=!1}){let o=We({claudeConfigDir:e,currentVersion:n}),i=[];if(o.canDelete)for(let r of o.entries)r.shouldDelete&&(t||O.rmSync(r.path,{recursive:!0,force:!0}),t||i.push(r));return{...o,deleted:i}}function ze({claudeConfigDir:e=Ve(),cwd:n=process.cwd()}={}){let t=_t(e),o=[Wn(w.join(n,".claude","frontend-craft.manifest.json"),"local"),Wn(w.join(e,"frontend-craft.manifest.json"),"global")].filter(i=>i!==void 0);return{native:t,cli:o,hasMultipleActiveSources:t.length+o.length>1}}function de(e){let n=["install sources:"];if(e.native.length===0&&e.cli.length===0)return n.push(" none detected"),n.join(`
|
|
44
45
|
`);for(let t of e.native){let o=[t.version,t.scope].filter(Boolean).join(", ");n.push(` native plugin: ${o||"installed"}${t.installPath?` (${t.installPath})`:""}`)}for(let t of e.cli)n.push(` ${t.scope} CLI: ${t.packageVersion??"unknown"} (${t.manifestPath})`);return e.hasMultipleActiveSources&&n.push(" warning: multiple active sources detected; keep one Claude loader as the source of truth"),n.join(`
|
|
45
|
-
`)}function
|
|
46
|
+
`)}function Re(e,n="report"){let t=["native cache:"];if(t.push(` current installs: ${e.currentInstallPaths.length?e.currentInstallPaths.join(", "):"unknown"}`),e.warning&&t.push(` warning: ${e.warning}`),e.entries.length===0)return t.push(" entries: none"),t.join(`
|
|
46
47
|
`);for(let o of e.entries){let i=o.isCurrent?"current install":o.reasons.length?o.reasons.join(", "):"healthy",r=n==="dry-run"&&o.shouldDelete?"would delete":n==="fix"&&o.shouldDelete?"delete":"keep";t.push(` ${r} ${o.version}: ${i}`)}return t.join(`
|
|
47
|
-
`)}function
|
|
48
|
-
`)}function
|
|
48
|
+
`)}function Bn(e,n){if(n)return Re(e,"dry-run");let t=[Re(e,"fix")];for(let o of e.deleted)t.push(` deleted ${o.version}: ${o.path}`);return e.deleted.length===0&&t.push(" deleted: none"),t.join(`
|
|
49
|
+
`)}function Ve(){return Lt(process.env.CLAUDE_CONFIG_DIR??w.join(Ue.homedir(),".claude"))}function Ft({cacheDir:e,currentInstallPaths:n,currentVersion:t}){if(!O.existsSync(e))return[];let o=new Set(n.map(Vn));return O.readdirSync(e,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>{let r=w.join(e,i.name),s=Pt(r),l=O.existsSync(w.join(r,"dist")),a=O.existsSync(w.join(r,".orphaned_at")),c=o.has(Vn(r)),u=[];return a&&u.push("orphaned"),l||u.push("missing dist"),s&&Et(s,t)<0&&u.push(`package ${s} < ${t}`),{version:i.name,path:r,isCurrent:c,hasDist:l,orphaned:a,packageVersion:s,reasons:u,shouldDelete:!c&&u.length>0}}).sort((i,r)=>i.version.localeCompare(r.version,void 0,{numeric:!0}))}function Mt(e){let n=w.join(e,"plugins","installed_plugins.json");if(!O.existsSync(n))return{paths:[],warning:`missing ${n}; refusing to delete cache entries`};try{let t=JSON.parse(O.readFileSync(n,"utf8")),o=(t.plugins?.["frontend-craft@bovinphang/frontend-craft"]??t.plugins?.["frontend-craft@frontend-craft"]??[]).map(i=>i.installPath).filter(i=>typeof i=="string"&&i.length>0).map(i=>w.resolve(i));return o.length===0?{paths:o,warning:`missing frontend-craft plugin entry in ${n}; refusing to delete cache entries`}:{paths:o}}catch{return{paths:[],warning:`invalid ${n}; refusing to delete cache entries`}}}function _t(e){let n=w.join(e,"plugins","installed_plugins.json");if(!O.existsSync(n))return[];try{let t=JSON.parse(O.readFileSync(n,"utf8"));return Object.entries(t.plugins??{}).flatMap(([o,i])=>Tt(o)?i.map(r=>({key:o,installPath:typeof r.installPath=="string"?w.resolve(r.installPath):void 0,scope:typeof r.scope=="string"?r.scope:void 0,version:typeof r.version=="string"?r.version:void 0})):[])}catch{return[]}}function Tt(e){return e==="frontend-craft@bovinphang/frontend-craft"||e==="frontend-craft@frontend-craft"||e.startsWith("frontend-craft@")}function Wn(e,n){if(O.existsSync(e))try{let t=JSON.parse(O.readFileSync(e,"utf8"));return t.runtime!=="claude"?void 0:{scope:n,manifestPath:e,packageVersion:typeof t.packageVersion=="string"?t.packageVersion:void 0}}catch{return{scope:n,manifestPath:e}}}function Pt(e){let n=w.join(e,"package.json");if(O.existsSync(n))try{let t=JSON.parse(O.readFileSync(n,"utf8"));return typeof t.version=="string"?t.version:void 0}catch{return}}function Et(e,n){let t=zn(e),o=zn(n);for(let i=0;i<3;i+=1)if(t[i]!==o[i])return t[i]-o[i];return 0}function zn(e){let n=e.match(/^(\d+)\.(\d+)\.(\d+)/);return n?[Number(n[1]),Number(n[2]),Number(n[3])]:[0,0,0]}function Lt(e){return e==="~"?Ue.homedir():e.startsWith("~/")||e.startsWith("~\\")?w.join(Ue.homedir(),e.slice(2)):e}function Vn(e){let n=w.resolve(e);return process.platform==="win32"?n.toLowerCase():n}function He(e){try{let n=d.join(e,"package.json");return JSON.parse(m.readFileSync(n,"utf8")).version??"0.0.0"}catch{return"0.0.0"}}function Gt(e){let n=null,t=!1,o=!1,i=!1,r=!1,s=!1,l,a=[];for(let c=0;c<e.length;c++){let u=e[c];u==="--global"||u==="-g"?(t=!0,n="global"):u==="--local"||u==="-l"?(o=!0,n="local"):u==="--dry-run"?i=!0:u==="--force"?r=!0:u==="--all"?s=!0:u==="--lang"?l=e[++c]??"":u.startsWith("--lang=")?l=u.slice(7):u.startsWith("-")||a.push(u)}return{runtime:a[0],installLocation:n,dryRun:i,force:r,all:s,hasGlobal:t,hasLocal:o,language:l}}function qe(){console.log(`frontend-craft - universal installer
|
|
49
50
|
|
|
50
51
|
Usage:
|
|
51
52
|
frontend-craft install <runtime> [options]
|
|
@@ -68,6 +69,7 @@ Usage:
|
|
|
68
69
|
Options:
|
|
69
70
|
--global, -g Install to tool global config directory
|
|
70
71
|
--local, -l Install to this project only
|
|
72
|
+
--lang <lang> Install content language: ${ve.join(", ")} (default: ${Q})
|
|
71
73
|
--dry-run Show actions without writing files
|
|
72
74
|
--force Uninstall: remove modified managed files (does not override Claude Marketplace)
|
|
73
75
|
--all Install for every supported runtime
|
|
@@ -81,5 +83,5 @@ Notes:
|
|
|
81
83
|
|
|
82
84
|
Runtimes:
|
|
83
85
|
${F.join(", ")}
|
|
84
|
-
`)}function
|
|
85
|
-
`)}function
|
|
86
|
+
`)}function Hn(e){let n=e[0];return n==null||["--dry-run","--all","--global","-g","--local","-l","--lang"].includes(n)||n.startsWith("--lang=")}async function Xn(e){let n=Hn(e)?"install":e[0],t=Hn(e)?e:e.slice(1),o=n==="setup",i=Gn(import.meta.url);if(n==="version"||n==="-v"||n==="--version"){console.log(He(i));return}if(n==="list"){F.forEach(h=>console.log(h));return}if(n==="matrix"){console.log(En(F));return}if(n==="doctor"){let h=t[0]??"claude",_=t.includes("--global")||t.includes("-g"),T=t.includes("--fix-cache"),G=t.includes("--dry-run"),B=process.cwd(),U=Y({runtime:h,isGlobal:_,cwd:B}),De=ke[h];if(!De){console.error(`Unknown runtime: ${h}`),process.exitCode=1;return}console.log(Bt({runtime:h,baseDir:U,cwd:B,cap:De,pluginRoot:i,fixCache:T,dryRun:G,isGlobal:_}));return}if(n==="sync-metadata"){let h=t.includes("--check"),_=Xt(i);if(_.length>0){for(let T of _)console.error(T);process.exitCode=1;return}console.log(h?"metadata is synchronized":"metadata is synchronized; no changes needed");return}if(n==="help"||n==="-h"||n==="--help"){qe();return}let r=n==="update"||n==="upgrade"?"update":"install";if(n!=="install"&&n!=="setup"&&n!=="update"&&n!=="upgrade"&&n!=="uninstall"&&n!=="remove"){console.error(`Unknown command: ${n}`),qe(),process.exitCode=1;return}if(t.some(h=>h==="help"||h==="--help"||h==="-h")){qe();return}let s=Gt(t),l=s.runtime,a=s.all,{installLocation:c,dryRun:u,force:g,hasGlobal:b,hasLocal:j}=s,R=s.language;if(R!==void 0&&!Ae(R)){console.error(`Unsupported language: ${R||"(missing)"}. Supported languages: ${ve.join(", ")}`),process.exitCode=1;return}let M=R;o&&l==="all"&&(l=void 0,a=!0);let pe=c??(o?"local":null);if(b&&j){console.error("--global and --local cannot be used together."),process.exitCode=1;return}let A=process.cwd();if(n==="uninstall"||n==="remove"){let h=Yn(j,b),T=we({cwd:A,runtimes:l?[l]:a?F:void 0,scopes:h});if(l&&!je[l]){console.error(`Unknown runtime: ${l}`),process.exitCode=1;return}if(T.length===0){console.log(Qn("uninstall",l,h));return}for(let G of T){console.log(`Uninstalling frontend-craft for "${G.runtime}" -> ${G.baseDir}${G.scope==="global"?" (global)":""}`);let B=Ge({install:G,cwd:A,dryRun:u,force:g});for(let U of B.removed)console.log(`${u?"[dry-run] would remove":"Removed"}${U.modified?" modified file":" file"}: ${U.path}`);for(let U of B.skipped)console.log(`Skipped modified file: ${U}`);for(let U of B.missing)console.log(`Missing file: ${U}`);u&&B.skipped.length===0&&console.log(`[dry-run] would remove manifest: ${G.manifestPath}`)}return}let me=!!process.stdin.isTTY||process.env.FRONTEND_CRAFT_FORCE_INTERACTIVE==="1";if(r==="update"&&!l){let h=Yn(j,b),_=we({cwd:A,runtimes:a?F:void 0,scopes:h});if(_.length===0){console.log(Qn("update",void 0,h));return}for(let T of _){let G=M??T.manifest.language??Q;await Kn({rt:T.runtime,mode:r,isGlobal:T.scope==="global",baseDir:T.baseDir,pluginRoot:i,cwd:A,dryRun:u,language:G})}return}let ie=a?F:l?[l]:[];ie.length||(me?ie=await Fn():(console.log("Non-interactive terminal detected, defaulting to claude runtime."),ie=["claude"]));let V=M;!V&&r==="install"&&(me?V=await _n():V=Q);let q;if(pe==="global"?q=!0:pe==="local"?q=!1:me?q=await Mn(ie):(console.log("Non-interactive terminal detected, defaulting to global install."),q=!0),!V&&r==="update"&&l){let h=Y({runtime:l,isGlobal:q,cwd:A});V=le(re(h))?.language??Q}V??=Tn(M);for(let h of ie){if(!je[h]){console.error(`Unknown runtime: ${h}`),process.exitCode=1;continue}let _=Y({runtime:h,isGlobal:q,cwd:A});await Kn({rt:h,mode:r,isGlobal:q,baseDir:_,pluginRoot:i,cwd:A,dryRun:u,force:g,canPrompt:me,language:V})}}async function Kn({rt:e,mode:n,isGlobal:t,baseDir:o,pluginRoot:i,cwd:r,dryRun:s,force:l,canPrompt:a,language:c}){let u=await Ut({rt:e,mode:n,isGlobal:t,cwd:r,dryRun:s,force:!!l,canPrompt:!!a});if(!u)return;u.redirect&&(t=u.redirect.isGlobal,o=u.redirect.baseDir,n="update");let g={pluginRoot:i,contentRoot:Pn(i,c),cwd:r,runtime:e,isGlobal:t,baseDir:o,dryRun:s,mode:n,language:c,capabilities:ke[e]};n==="install"?(console.log(`Installing frontend-craft for "${e}" -> ${o}${t?" (global)":""}`),!s&&m.existsSync(re(o))&&console.log(`Existing frontend-craft manifest found; use "frontend-craft update ${e}" to refresh managed files.`)):console.log(`Updating frontend-craft for "${e}" -> ${o}${t?" (global)":""}`),s||Ke({baseDir:o,cwd:r,mode:n,packageVersion:He(i),runtime:e,isGlobal:t,language:c});try{await je[e](g),s||Je()}catch(b){throw s||Ye(),b}}async function Ut({rt:e,mode:n,isGlobal:t,cwd:o,dryRun:i,force:r,canPrompt:s}){if(e!=="claude")return{};let l=ze({cwd:o});if(l.native.length>0){console.log("Claude Code Marketplace install detected for frontend-craft."),console.log(de(l)),console.log("Update frontend-craft through Claude Code Marketplace. CLI install/update is disabled while Marketplace is active."),process.exitCode=1;return}let a=t?"cli-global":"cli-local",c=l.cli.filter(R=>Be(R)!==a);if(c.length===0)return l.hasMultipleActiveSources&&console.log(de(l)),{};let u=c[0],g=Be(u);if(console.log(`${X(g)} install detected for frontend-craft.`),console.log(de(l)),i){console.log(`[dry-run] resolve the existing ${X(g)} source before using ${X(a)}.`),process.exitCode=1;return}if(!s){zt(g,a),process.exitCode=1;return}if(await Vt(g,a)==="switch"){if(!Wt({installs:c,cwd:o,dryRun:i,force:r})){process.exitCode=1;return}return{}}let j=g==="cli-global";return{redirect:{isGlobal:j,baseDir:Y({runtime:"claude",isGlobal:j,cwd:o})}}}function Wt({installs:e,cwd:n,dryRun:t,force:o}){for(let i of e){let r=we({cwd:n,runtimes:["claude"],scopes:[i.scope]})[0];if(!r)continue;console.log(`Uninstalling existing ${X(Be(i))} install before switching source.`);let s=Ge({install:r,cwd:n,dryRun:t,force:o});for(let l of s.removed)console.log(`${t?"[dry-run] would remove":"Removed"}${l.modified?" modified file":" file"}: ${l.path}`);for(let l of s.skipped)console.log(`Skipped modified file: ${l}`);for(let l of s.missing)console.log(`Missing file: ${l}`);if(s.skipped.length>0)return console.log("Resolve skipped modified files or rerun with --force before switching Claude CLI install source."),!1}return!0}function zt(e,n){let t=Jn(e),o=Jn(n);console.log(`Keep the existing source updated with: frontend-craft update claude ${t}`),console.log(`Or switch sources with: frontend-craft uninstall claude ${t} && frontend-craft install claude ${o}`)}async function Vt(e,n){return console.log("Choose how to resolve the Claude CLI install source conflict:"),console.log(` 1. Keep ${X(e)} and update it`),console.log(` 2. Uninstall ${X(e)} and install ${X(n)}`),(await qt("Choice [1]: ")).trim()==="2"?"switch":"keep"}function qt(e){return process.env.FRONTEND_CRAFT_FORCE_INTERACTIVE==="1"&&!process.stdin.isTTY?(process.stdout.write(e),Promise.resolve(m.readFileSync(0,"utf8").split(/\r?\n/)[0]??"")):new Promise(n=>{let t=At.createInterface({input:process.stdin,output:process.stdout});t.question(e,o=>{t.close(),n(o)}),t.on("close",()=>n(""))})}function Be(e){return e.scope==="global"?"cli-global":"cli-local"}function X(e){return e==="marketplace"?"Claude Code Marketplace":e==="cli-global"?"Claude CLI global":"Claude CLI local"}function Jn(e){return e==="cli-global"?"--global":"--local"}function Yn(e,n){return e?["local"]:n?["global"]:["local","global"]}function Qn(e,n,t){return`No frontend-craft installs found${n?` for "${n}"`:""} to ${e} (${t.join(", ")}).`}function Bt({runtime:e,baseDir:n,cwd:t,cap:o,pluginRoot:i,fixCache:r,dryRun:s,isGlobal:l}){let a=[`frontend-craft doctor: ${e}`,`baseDir: ${n}`,`tier: ${o.tier}`];if(a.push(`skills: ${se(Ht(e,n,t),o.skills)}`),a.push(`agents: ${se(m.existsSync(d.join(n,"agents")),o.agents)}`),a.push(`commands: ${se(Kt(e,n),o.commands)}`),a.push(`hooks: ${se(Jt(e,n),o.hooks)}`),a.push(`rules: ${se(Yt(e,n),o.rules&&!l)}`),a.push(`templates: ${se(Qt(e,n,t),o.templates)}`),e==="claude"){let c=He(i);a.push(de(ze({cwd:t}))),r?a.push(Bn(qn({currentVersion:c,dryRun:s}),s)):a.push(Re(We({currentVersion:c})))}return a.join(`
|
|
87
|
+
`)}function se(e,n){return n?e?"ok":"missing":"not expected"}function Ht(e,n,t){return e==="codex"?m.existsSync(d.join(t,".agents","skills","fec-react-project-standard")):e==="gemini"?m.existsSync(d.join(n,"extensions","frontend-craft","skills","fec-react-project-standard")):m.existsSync(d.join(n,"skills","fec-react-project-standard"))}function Kt(e,n){let t=e==="windsurf"?d.join(n,"workflows"):e==="opencode"||e==="kilo"?d.join(n,"command"):e==="copilot"?d.join(n,"prompts"):d.join(n,"commands");return m.existsSync(d.join(t,"fec-init.md"))}function Jt(e,n){return e==="qoder"?m.existsSync(d.join(n,"settings.json"))&&m.existsSync(d.join(n,"hooks","fec-security-check.js")):m.existsSync(d.join(n,"hooks.json"))}function Yt(e,n){return e==="copilot"?m.existsSync(d.join(n,"instructions","frontend-craft.instructions.md")):e==="cline"?m.existsSync(d.join(n,".clinerules")):m.existsSync(d.join(n,"rules"))}function Qt(e,n,t){return e==="claude"?m.existsSync(d.join(t,".claude-plugin","plugin.json")):e==="codex"?m.existsSync(d.join(t,"AGENTS.md"))||m.existsSync(d.join(n,"config.toml")):e==="gemini"?m.existsSync(d.join(t,"GEMINI.md")):e==="openclaw"?m.existsSync(d.join(t,"AGENTS.md")):e==="qoder"?m.existsSync(d.join(n,"settings.json")):e==="opencode"?m.existsSync(d.join(n,"opencode.jsonc")):!1}function Xt(e){let n=[],t=JSON.parse(m.readFileSync(d.join(e,"package.json"),"utf8")),o=[[".claude-plugin/plugin.json","version"],[".claude-plugin/marketplace.json","plugins.0.version"],["openclaw.plugin.json","version"]];for(let[c,u]of o){let g=d.join(e,c),b=JSON.parse(m.readFileSync(g,"utf8")),j=u.split(".").reduce((R,M)=>R?.[Number.isNaN(Number(M))?M:Number(M)],b);j!==t.version&&n.push(`${c} ${u} is ${j}, expected ${t.version}`)}let i=JSON.parse(m.readFileSync(d.join(e,"skills","metadata.json"),"utf8"));for(let c of i)c.version!==t.version&&n.push(`skills/metadata.json ${c.id}.version is ${c.version}, expected ${t.version}`);let r=m.readdirSync(d.join(e,"commands")).filter(c=>c.endsWith(".md")).length,s=m.readdirSync(d.join(e,"skills"),{withFileTypes:!0}).filter(c=>c.isDirectory()).length,l=m.readdirSync(d.join(e,"agents")).filter(c=>c.endsWith(".md")).length,a=m.readFileSync(d.join(e,".claude-plugin","marketplace.json"),"utf8");return a.includes(`${l} agents`)||n.push(`marketplace description must mention ${l} agents`),a.includes(`${s} skills`)||n.push(`marketplace description must mention ${s} skills`),a.includes(`${r} commands`)||n.push(`marketplace description must mention ${r} commands`),n}Xn(process.argv.slice(2)).catch(e=>{console.error(e),process.exit(1)});
|