@bovinphang/frontend-craft 2.5.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 +61 -0
- package/.claude-plugin/plugin.json +32 -0
- package/.mcp.json +44 -0
- package/CHANGELOG.md +229 -0
- package/CHANGELOG.zh-CN.md +228 -0
- package/CODE_OF_CONDUCT.md +34 -0
- package/CODE_OF_CONDUCT.zh-CN.md +34 -0
- package/CONTRIBUTING.md +356 -0
- package/CONTRIBUTING.zh-CN.md +356 -0
- package/LICENSE +21 -0
- package/README.md +467 -0
- package/README.openclaw.md +262 -0
- package/README.openclaw.zh-CN.md +262 -0
- package/README.zh-CN.md +467 -0
- package/SECURITY.md +44 -0
- package/SECURITY.zh-CN.md +44 -0
- package/agents/fec-architect.md +125 -0
- package/agents/fec-code-reviewer.md +152 -0
- package/agents/fec-debugger.md +44 -0
- package/agents/fec-design-token-mapper.md +75 -0
- package/agents/fec-doc-updater.md +30 -0
- package/agents/fec-e2e-runner.md +107 -0
- package/agents/fec-figma-implementer.md +104 -0
- package/agents/fec-performance-optimizer.md +293 -0
- package/agents/fec-refactor-cleaner.md +32 -0
- package/agents/fec-security-reviewer.md +116 -0
- package/agents/fec-test-planner.md +50 -0
- package/agents/fec-typescript-reviewer.md +142 -0
- package/agents/fec-ui-checker.md +120 -0
- package/commands/fec-debug.md +30 -0
- package/commands/fec-doc-sync.md +18 -0
- package/commands/fec-init.md +70 -0
- package/commands/fec-plan.md +94 -0
- package/commands/fec-refactor-clean.md +19 -0
- package/commands/fec-review.md +66 -0
- package/commands/fec-scaffold.md +205 -0
- package/commands/fec-tdd.md +21 -0
- package/dist/bin/frontend-craft.js +82 -0
- package/dist/hooks/fec-cleanup-claude-cache.js +4 -0
- package/dist/hooks/fec-format-changed-file.js +1 -0
- package/dist/hooks/fec-notify.js +1 -0
- package/dist/hooks/fec-run-tests.js +1 -0
- package/dist/hooks/fec-security-check.js +2 -0
- package/dist/hooks/fec-session-start.js +1 -0
- package/docs/example-prompts.md +124 -0
- package/docs/ja-JP/README.md +467 -0
- package/docs/ko-KR/README.md +467 -0
- package/docs/project-structure.md +119 -0
- package/docs/runtimes/antigravity.md +10 -0
- package/docs/runtimes/augment.md +10 -0
- package/docs/runtimes/claude.md +171 -0
- package/docs/runtimes/claude.zh-CN.md +169 -0
- package/docs/runtimes/cline.md +10 -0
- package/docs/runtimes/codebuddy.md +10 -0
- package/docs/runtimes/codex.md +10 -0
- package/docs/runtimes/copilot.md +10 -0
- package/docs/runtimes/cursor.md +10 -0
- package/docs/runtimes/gemini.md +10 -0
- package/docs/runtimes/kilo.md +10 -0
- package/docs/runtimes/openclaw.md +10 -0
- package/docs/runtimes/opencode.md +10 -0
- package/docs/runtimes/qoder.md +19 -0
- package/docs/runtimes/trae.md +10 -0
- package/docs/runtimes/windsurf.md +10 -0
- 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 +124 -0
- package/docs/zh-CN/project-structure.md +119 -0
- package/docs/zh-TW/README.md +467 -0
- package/hooks/hooks.json +71 -0
- package/openclaw.plugin.json +26 -0
- package/package.json +101 -0
- package/skills/TEMPLATE.md +155 -0
- package/skills/eval_queries.json +890 -0
- package/skills/fec-accessibility-check/SKILL.md +39 -0
- package/skills/fec-accessibility-check/references/report-template.md +23 -0
- package/skills/fec-accessibility-check/references/screen-reader-testing.md +33 -0
- package/skills/fec-api-integration/SKILL.md +78 -0
- package/skills/fec-api-integration/references/integration-patterns.md +80 -0
- package/skills/fec-browser-storage/SKILL.md +34 -0
- package/skills/fec-browser-storage/references/storage-patterns.md +65 -0
- package/skills/fec-canvas-threejs/SKILL.md +66 -0
- package/skills/fec-canvas-threejs/references/rendering-patterns.md +67 -0
- package/skills/fec-canvas-threejs/references/shader-webgl-patterns.md +67 -0
- package/skills/fec-code-review/SKILL.md +135 -0
- package/skills/fec-code-review/references/report-template.md +29 -0
- package/skills/fec-component-testing/SKILL.md +119 -0
- package/skills/fec-data-fetching/SKILL.md +62 -0
- package/skills/fec-data-fetching/references/query-patterns.md +77 -0
- package/skills/fec-debug-framework/SKILL.md +162 -0
- package/skills/fec-dependency-upgrade/SKILL.md +34 -0
- package/skills/fec-dependency-upgrade/references/dependency-upgrade-workflow.md +56 -0
- package/skills/fec-doc-sync/SKILL.md +37 -0
- package/skills/fec-e2e-testing/SKILL.md +40 -0
- package/skills/fec-e2e-testing/references/e2e-advanced.md +176 -0
- package/skills/fec-e2e-testing/references/playwright-patterns.md +95 -0
- package/skills/fec-form-handling/SKILL.md +76 -0
- package/skills/fec-form-handling/references/advanced-form-patterns.md +72 -0
- package/skills/fec-implement-from-design/SKILL.md +122 -0
- package/skills/fec-implement-from-design/references/design-plan-template.md +36 -0
- package/skills/fec-legacy-to-modern-migration/SKILL.md +180 -0
- package/skills/fec-legacy-to-modern-migration/references/migration-report-template.md +41 -0
- package/skills/fec-legacy-web-standard/SKILL.md +35 -0
- package/skills/fec-legacy-web-standard/references/legacy-patterns.md +85 -0
- package/skills/fec-list-virtualization/SKILL.md +34 -0
- package/skills/fec-list-virtualization/references/virtualization-patterns.md +52 -0
- package/skills/fec-monorepo-project-standard/SKILL.md +142 -0
- package/skills/fec-motion-interaction/SKILL.md +66 -0
- package/skills/fec-motion-interaction/references/motion-patterns.md +112 -0
- package/skills/fec-nextjs-project-standard/SKILL.md +117 -0
- package/skills/fec-nuxt-project-standard/SKILL.md +122 -0
- package/skills/fec-performance-optimization/SKILL.md +72 -0
- package/skills/fec-pwa-implementation/SKILL.md +36 -0
- package/skills/fec-pwa-implementation/references/manifest-and-icons.md +53 -0
- package/skills/fec-pwa-implementation/references/service-worker-workbox.md +68 -0
- package/skills/fec-react-project-standard/SKILL.md +83 -0
- package/skills/fec-react-project-standard/references/react-project-details.md +642 -0
- package/skills/fec-refactor-clean/SKILL.md +48 -0
- package/skills/fec-responsive-layout/SKILL.md +34 -0
- package/skills/fec-responsive-layout/references/responsive-layout-patterns.md +59 -0
- package/skills/fec-route-protection/SKILL.md +135 -0
- package/skills/fec-security-review/SKILL.md +38 -0
- package/skills/fec-security-review/references/report-template.md +27 -0
- package/skills/fec-security-review/references/security-checklist.md +64 -0
- package/skills/fec-source-driven-development/SKILL.md +61 -0
- package/skills/fec-state-management/SKILL.md +140 -0
- package/skills/fec-state-management/references/state-patterns.md +109 -0
- package/skills/fec-storybook-component-doc/SKILL.md +37 -0
- package/skills/fec-storybook-component-doc/references/story-patterns.md +118 -0
- package/skills/fec-svg-animation/SKILL.md +148 -0
- package/skills/fec-tailwind-design-system/SKILL.md +34 -0
- package/skills/fec-tailwind-design-system/references/tailwind-system-patterns.md +55 -0
- package/skills/fec-tdd-workflow/SKILL.md +52 -0
- package/skills/fec-testing-strategy/SKILL.md +45 -0
- package/skills/fec-typescript-type-safety/SKILL.md +157 -0
- package/skills/fec-typescript-type-safety/references/type-safety-patterns.md +102 -0
- package/skills/fec-ui-design/SKILL.md +90 -0
- package/skills/fec-ui-design/data/product-rules.json +110 -0
- package/skills/fec-ui-design/data/stack-ui-rules.json +14 -0
- package/skills/fec-ui-design/data/style-archetypes.json +74 -0
- package/skills/fec-ui-design/data/ux-quality-rules.json +56 -0
- package/skills/fec-ui-design/references/design-intelligence.md +37 -0
- package/skills/fec-ui-design/references/master-page-overrides.md +30 -0
- package/skills/fec-ui-design/references/pre-delivery-checklist.md +33 -0
- package/skills/fec-ui-design/scripts/design-system.mjs +530 -0
- package/skills/fec-validation-fix/SKILL.md +48 -0
- package/skills/fec-vite-project-standard/SKILL.md +83 -0
- package/skills/fec-vue3-project-standard/SKILL.md +49 -0
- package/skills/fec-vue3-project-standard/references/vue3-project-details.md +547 -0
- package/skills/fec-web-workers/SKILL.md +36 -0
- package/skills/fec-web-workers/references/advanced-workers.md +54 -0
- package/skills/fec-web-workers/references/basic-worker.md +67 -0
- package/skills/metadata.json +1422 -0
- package/skills/relations.json +644 -0
- package/templates/claude/CLAUDE.md +106 -0
- package/templates/claude/settings.json +62 -0
- package/templates/codex/AGENTS.md +105 -0
- package/templates/codex/config.toml +32 -0
- package/templates/openclaw/AGENTS.md +101 -0
- package/templates/openclaw/OPENCLAW-CONFIG.md +12 -0
- package/templates/shared/rules/fec-agent-workflow.md +54 -0
- package/templates/shared/rules/fec-api-layer.md +99 -0
- package/templates/shared/rules/fec-ci-cd.md +128 -0
- package/templates/shared/rules/fec-code-comments.md +33 -0
- package/templates/shared/rules/fec-design-system.md +248 -0
- package/templates/shared/rules/fec-error-handling.md +200 -0
- package/templates/shared/rules/fec-git-conventions.md +73 -0
- package/templates/shared/rules/fec-i18n.md +112 -0
- package/templates/shared/rules/fec-naming-conventions.md +120 -0
- package/templates/shared/rules/fec-performance.md +101 -0
- package/templates/shared/rules/fec-react.md +82 -0
- package/templates/shared/rules/fec-refactoring.md +43 -0
- package/templates/shared/rules/fec-rendering-patterns.md +183 -0
- package/templates/shared/rules/fec-responsive-design.md +227 -0
- package/templates/shared/rules/fec-source-driven-development.md +31 -0
- package/templates/shared/rules/fec-state-management.md +163 -0
- package/templates/shared/rules/fec-testing.md +98 -0
- package/templates/shared/rules/fec-typescript.md +355 -0
- package/templates/shared/rules/fec-vue.md +64 -0
- package/templates/shared/rules/fec-working-modes.md +50 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import m from"node:fs";import d from"node:path";import xt from"node:readline";import j from"node:path";import H from"node:fs";import k from"node:fs";import v from"node:path";import Wn from"node:crypto";import Vn from"node:os";var z;function Ae({baseDir:e,cwd:n=process.cwd(),mode:t,packageVersion:o,runtime:i,isGlobal:r}){let s=v.join(e,"frontend-craft.manifest.json");z={baseDir:v.resolve(e),cwd:v.resolve(n),homeDir:v.resolve(Vn.homedir()),mode:t,packageVersion:o,runtime:i,scope:r?"global":"local",manifestPath:s,previousFiles:qn(s),writtenFiles:new Map,skippedFiles:new Set}}function Ge(){let e=z;if(z=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])=>qe(o,i)).sort((o,i)=>o.path.localeCompare(i.path)),t={packageVersion:e.packageVersion,runtime:e.runtime,scope:e.scope,installedAt:new Date().toISOString(),files:n};f(v.dirname(e.manifestPath)),k.writeFileSync(e.manifestPath,`${JSON.stringify(t,null,2)}
|
|
3
|
+
`,"utf8")}function Le(){z=void 0}function le(e){return v.join(e,"frontend-craft.manifest.json")}function xe(e){if(k.existsSync(e))try{let n=JSON.parse(k.readFileSync(e,"utf8"));return{...n,files:(n.files??[]).map(t=>({...t,path:ve(t.path)}))}}catch{return}}function qn(e){let n=xe(e);return new Map((n?.files??[]).map(t=>[Ve(t.root??"baseDir",ve(t.path)),t.hash]))}function Ue(e){return Wn.createHash("sha256").update(e).digest("hex")}function Ie(e){return Ue(k.readFileSync(e))}function We(e){let n=z;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 Ve(i,ve(s))}}function ve(e){return e.split(v.sep).join("/")}function Ve(e,n){return`${e}:${n}`}function qe(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 Be(e){let n=z,t=We(e);if(!n||!t||n.mode!=="update"||!k.existsSync(e))return!1;let o=n.previousFiles.get(t);return!o||Ie(e)===o?!1:(n.skippedFiles.add(t),console.log(`Skipped modified file: ${qe(t,o).path}`),!0)}function ze(e,n){let t=z,o=We(e);!t||!o||t.writtenFiles.set(o,Ue(n))}function f(e){k.existsSync(e)||k.mkdirSync(e,{recursive:!0})}function D(e,n){if(Be(n))return;f(v.dirname(n));let t=k.readFileSync(e);k.copyFileSync(e,n),ze(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){Be(e)||(f(v.dirname(e)),k.writeFileSync(e,n,"utf8"),ze(e,n))}function Bn(e,n){let t=j.resolve(e);return n.replaceAll("${CLAUDE_PLUGIN_ROOT}",t).replaceAll("${FRONTEND_CRAFT_ROOT}",t)}function zn(e){let n=j.join(e,"hooks","hooks.json"),t=C(n);return Bn(e,t)}async function He(e){let{pluginRoot:n,baseDir:t,dryRun:o,cwd:i,isGlobal:r}=e;if(o){console.log(`[dry-run] would install Claude Code files into ${t}`);return}f(t),p(j.join(n,"skills"),j.join(t,"skills")),p(j.join(n,"agents"),j.join(t,"agents")),p(j.join(n,"commands"),j.join(t,"commands")),r||p(j.join(n,"templates","shared","rules"),j.join(t,"rules"));let s=j.join(n,"templates","claude");if(H.existsSync(s))for(let l of H.readdirSync(s)){let c=j.join(t,l);H.existsSync(c)||D(j.join(s,l),c)}if(y(j.join(t,"hooks.json"),zn(n)),!r&&H.existsSync(j.join(n,".mcp.json"))){let l=j.join(i,".mcp.json");H.existsSync(l)||D(j.join(n,".mcp.json"),l)}let a=j.join(n,".claude-plugin","plugin.json");if(!r&&H.existsSync(a)){f(j.join(i,".claude-plugin")),D(a,j.join(i,".claude-plugin","plugin.json"));let l=j.join(n,".claude-plugin","marketplace.json");H.existsSync(l)&&D(l,j.join(i,".claude-plugin","marketplace.json"))}}import $ from"node:path";import oe from"node:fs";import Hn from"node:os";function Ke(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(),a=o.match(/^description:\s*(.+)$/m),l=a?a[1].trim():"";return`name = "${s}"
|
|
4
|
+
description = "${(u=>u.replace(/\\/g,"\\\\").replace(/"/g,'\\"'))(l)}"
|
|
5
|
+
|
|
6
|
+
model = "gpt-5.4"
|
|
7
|
+
model_reasoning_effort = "high"
|
|
8
|
+
|
|
9
|
+
developer_instructions = """
|
|
10
|
+
`+i+`
|
|
11
|
+
"""
|
|
12
|
+
`}async function Je(e){let{pluginRoot:n,baseDir:t,cwd:o,dryRun:i,isGlobal:r}=e,s=$.join(n,"agents"),a=$.join(t,"agents"),l=$.join(t,"rules"),c=r?$.join(Hn.homedir(),".agents","skills"):$.join(o,".agents","skills");if(i){console.log(`[dry-run] codex: ${t}, agents -> ${a}, skills -> ${c}`);return}f(a),f(c);for(let b of oe.readdirSync(s)){if(!b.endsWith(".md"))continue;let I=C($.join(s,b)),M=Ke(I,b);y($.join(a,b.replace(/\.md$/,".toml")),M)}p($.join(n,"skills"),c);let u=$.join(n,"templates","shared","rules");!r&&oe.existsSync(u)&&p(u,l);let g=$.join(n,"templates","codex","AGENTS.md"),R=$.join(n,"templates","codex","config.toml");if(!r&&oe.existsSync(g)){let b=$.join(o,"AGENTS.md");oe.existsSync(b)||D(g,b)}oe.existsSync(R)&&D(R,$.join(t,"config.toml"))}import Y from"node:path";import Ye from"node:fs";async function Qe(e){let{pluginRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o){console.log(`[dry-run] cursor -> ${t}`);return}f(t);let r=Y.join(t,"skills");p(Y.join(n,"skills"),r);let s=Y.join(n,"templates","shared","rules"),a=Y.join(t,"rules");if(!i&&Ye.existsSync(s)){f(a);for(let l of Ye.readdirSync(s)){if(!l.endsWith(".md"))continue;let c=C(Y.join(s,l)),u=l.replace(/\.md$/,""),g=`---
|
|
13
|
+
description: Frontend Craft - ${u}
|
|
14
|
+
globs: "**/*.{ts,tsx,vue,js,jsx,css,scss,less,html}"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
`+c+`
|
|
18
|
+
`;y(Y.join(a,`${u}.mdc`),g)}}}import E from"node:path";import ke from"node:fs";async function Xe(e){let{pluginRoot: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 a=E.join(n,"commands");for(let c of ke.readdirSync(a)){if(!c.endsWith(".md"))continue;let u=C(E.join(a,c));y(E.join(r,c),u)}let l=E.join(n,"templates","shared","rules");if(!i&&ke.existsSync(l)){f(s);for(let c of ke.readdirSync(l)){if(!c.endsWith(".md"))continue;let u=C(E.join(l,c));y(E.join(s,c),u)}}p(E.join(n,"skills"),E.join(t,"skills"))}import A from"node:path";import se from"node:fs";async function ae(e){let{pluginRoot:n,baseDir:t,dryRun:o}=e,i=A.join(t,"command");if(o){console.log(`[dry-run] opencode/kilo commands -> ${i}`);return}f(i);let r=A.join(n,"commands");for(let c of se.readdirSync(r)){if(!c.endsWith(".md"))continue;let u=C(A.join(r,c));y(A.join(i,c),u)}let s=A.join(t,"skills");f(s);let a=A.join(n,"skills");for(let c of se.readdirSync(a)){let u=A.join(a,c);if(!se.statSync(u).isDirectory())continue;let g=A.join(u,"SKILL.md");if(se.existsSync(g)){let R=A.join(s,c);p(u,R)}}let l=A.join(t,"opencode.jsonc");e.runtime==="opencode"&&!se.existsSync(l)&&y(l,`{
|
|
19
|
+
"$schema": "https://opencode.ai/config.json",
|
|
20
|
+
"permissions": { "bash": "allow" }
|
|
21
|
+
}
|
|
22
|
+
`)}async function Ze(e){return ae(e)}async function en(e){return ae(e)}import ie from"node:path";import nn from"node:fs";async function tn(e){let{pluginRoot:n,baseDir:t,cwd:o,dryRun:i,isGlobal:r}=e;if(i){console.log(`[dry-run] gemini -> ${t}`);return}f(t);let s=ie.join(t,"extensions","frontend-craft");f(s),p(ie.join(n,"skills"),ie.join(s,"skills"));let a=ie.join(n,"templates","claude","CLAUDE.md"),l=ie.join(o,"GEMINI.md");if(!r&&!nn.existsSync(l)&&nn.existsSync(a)){let c=C(a).replaceAll(".claude/",".gemini/").replaceAll("CLAUDE.md","GEMINI.md");y(l,c)}}import U from"node:path";import we from"node:fs";async function on(e){let{pluginRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o){console.log(`[dry-run] copilot -> ${t}`);return}f(t);let r=U.join(t,"instructions"),s=U.join(t,"prompts");if(f(s),!i){f(r);let l=U.join(n,"templates","shared","rules"),c=[`# Frontend Craft - Copilot instructions
|
|
23
|
+
`];if(we.existsSync(l))for(let u of we.readdirSync(l))u.endsWith(".md")&&c.push(`
|
|
24
|
+
## ${u}
|
|
25
|
+
|
|
26
|
+
`,C(U.join(l,u)));y(U.join(r,"frontend-craft.instructions.md"),c.join(""))}let a=U.join(n,"commands");for(let l of we.readdirSync(a))l.endsWith(".md")&&y(U.join(s,l),C(U.join(a,l)))}import Q from"node:path";async function sn(e){let{pluginRoot:n,baseDir:t,dryRun:o}=e;if(o)return console.log(`[dry-run] antigravity -> ${t}`);f(t),p(Q.join(n,"skills"),Q.join(t,"skills"))}async function rn(e){let{pluginRoot:n,baseDir:t,dryRun:o}=e;if(o)return console.log(`[dry-run] augment -> ${t}`);f(t),p(Q.join(n,"skills"),Q.join(t,"skills"))}async function ln(e){let{pluginRoot:n,baseDir:t,dryRun:o}=e;if(o)return console.log(`[dry-run] codebuddy -> ${t}`);f(t),p(Q.join(n,"skills"),Q.join(t,"skills"))}import ce from"node:path";import an from"node:fs";async function cn(e){let{pluginRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o)return console.log(`[dry-run] trae -> ${t}`);if(i)return;let r=ce.join(t,"rules");f(r);let s=ce.join(n,"templates","shared","rules"),a=[`# Frontend Craft - Trae rules bundle
|
|
27
|
+
`];if(an.existsSync(s))for(let l of an.readdirSync(s))l.endsWith(".md")&&a.push(`
|
|
28
|
+
## ${l}
|
|
29
|
+
|
|
30
|
+
`,C(ce.join(s,l)));y(ce.join(r,"frontend-craft.md"),a.join(""))}import ue from"node:path";import un from"node:fs";async function fn(e){let{pluginRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o)return console.log(`[dry-run] cline -> ${ue.join(t,".clinerules")}`);if(i)return;let r=ue.join(n,"templates","shared","rules"),s=[`# Frontend Craft - Cline rules
|
|
31
|
+
`];if(un.existsSync(r))for(let a of un.readdirSync(r))a.endsWith(".md")&&s.push(`
|
|
32
|
+
## ${a}
|
|
33
|
+
|
|
34
|
+
`,C(ue.join(r,a)));y(ue.join(t,".clinerules"),s.join(""))}import K from"node:path";import Re from"node:fs";async function dn(e){let{pluginRoot:n,baseDir:t,cwd:o,dryRun:i}=e;if(i)return console.log(`[dry-run] openclaw -> ${t}`);f(t),p(K.join(n,"skills"),K.join(t,"skills")),p(K.join(n,"commands"),K.join(t,"commands"));let r=K.join(n,"templates","openclaw");if(Re.existsSync(r))for(let s of Re.readdirSync(r)){if(!s.endsWith(".md"))continue;let a=K.join(o,s);Re.existsSync(a)||D(K.join(r,s),a)}}import O from"node:path";import pn from"node:fs";var Kn=["fec-security-check.js","fec-format-changed-file.js","fec-run-tests.js","fec-notify.js"];async function mn(e){let{pluginRoot:n,baseDir:t,dryRun:o,isGlobal:i}=e;if(o){console.log(`[dry-run] qoder -> ${t}`);return}f(t),p(O.join(n,"skills"),O.join(t,"skills")),p(O.join(n,"commands"),O.join(t,"commands")),p(O.join(n,"agents"),O.join(t,"agents")),i||p(O.join(n,"templates","shared","rules"),O.join(t,"rules")),Jn(n,O.join(t,"hooks")),y(O.join(t,"settings.json"),JSON.stringify(Yn(t),null,2)+`
|
|
35
|
+
`)}function Jn(e,n){f(n);for(let t of Kn){let o=O.join(e,"dist","hooks",t);if(!pn.existsSync(o))throw new Error(`Missing built hook script: ${o}. Run "npm run build" before installing.`);D(o,O.join(n,t))}}function Yn(e){let n=O.join(e,"settings.json"),t=Qn(n);return{...t,hooks:{...X(t.hooks),PreToolUse:[...de(X(t.hooks).PreToolUse),fe("Bash|Shell",".qoder/hooks/fec-security-check.js","Checking command safety...")],PostToolUse:[...de(X(t.hooks).PostToolUse),fe("Write|Edit|MultiEdit",".qoder/hooks/fec-format-changed-file.js","Running formatter...")],Stop:[...de(X(t.hooks).Stop),fe(".*",".qoder/hooks/fec-run-tests.js","Running final validation...")],Notification:[...de(X(t.hooks).Notification),fe(".*",".qoder/hooks/fec-notify.js")]}}}function Qn(e){if(!pn.existsSync(e))return{};try{let n=JSON.parse(C(e));return X(n)}catch{return{}}}function fe(e,n,t){return{matcher:e,hooks:[{type:"command",command:`node "${n}"`,...t?{statusMessage:t}:{}}]}}function X(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)?e:{}}function de(e){return Array.isArray(e)?e:[]}var F=["claude","codex","cursor","windsurf","opencode","kilo","gemini","copilot","antigravity","augment","trae","codebuddy","cline","openclaw","qoder"],pe={claude:He,codex:Je,cursor:Qe,windsurf:Xe,opencode:Ze,kilo:en,gemini:tn,copilot:on,antigravity:sn,augment:rn,trae:cn,codebuddy:ln,cline:fn,openclaw:dn,qoder:mn};import Xn from"node:fs";import Zn from"node:os";import et from"node:path";import ge from"node:readline";import gn from"node:os";import S from"node:path";function x(e){return e&&(e.startsWith("~/")||e==="~"?S.join(gn.homedir(),e.slice(1)):e)}function me(e){let n=gn.homedir(),t=process.env;switch(e){case"claude":return t.CLAUDE_CONFIG_DIR?x(t.CLAUDE_CONFIG_DIR):S.join(n,".claude");case"cursor":return t.CURSOR_CONFIG_DIR?x(t.CURSOR_CONFIG_DIR):S.join(n,".cursor");case"gemini":return t.GEMINI_CONFIG_DIR?x(t.GEMINI_CONFIG_DIR):S.join(n,".gemini");case"codex":return t.CODEX_HOME?x(t.CODEX_HOME):S.join(n,".codex");case"copilot":return t.COPILOT_CONFIG_DIR?x(t.COPILOT_CONFIG_DIR):S.join(n,".copilot");case"antigravity":return t.ANTIGRAVITY_CONFIG_DIR?x(t.ANTIGRAVITY_CONFIG_DIR):S.join(n,".gemini","antigravity");case"windsurf":return t.WINDSURF_CONFIG_DIR?x(t.WINDSURF_CONFIG_DIR):S.join(n,".codeium","windsurf");case"augment":return t.AUGMENT_CONFIG_DIR?x(t.AUGMENT_CONFIG_DIR):S.join(n,".augment");case"trae":return t.TRAE_CONFIG_DIR?x(t.TRAE_CONFIG_DIR):S.join(n,".trae");case"codebuddy":return t.CODEBUDDY_CONFIG_DIR?x(t.CODEBUDDY_CONFIG_DIR):S.join(n,".codebuddy");case"cline":return t.CLINE_CONFIG_DIR?x(t.CLINE_CONFIG_DIR):S.join(n,".cline");case"opencode":return t.OPENCODE_CONFIG_DIR?x(t.OPENCODE_CONFIG_DIR):t.XDG_CONFIG_HOME?S.join(x(t.XDG_CONFIG_HOME),"opencode"):S.join(n,".config","opencode");case"kilo":return t.KILO_CONFIG_DIR?x(t.KILO_CONFIG_DIR):t.XDG_CONFIG_HOME?S.join(x(t.XDG_CONFIG_HOME),"kilo"):S.join(n,".config","kilo");case"openclaw":return t.OPENCLAW_CONFIG_DIR?x(t.OPENCLAW_CONFIG_DIR):S.join(n,".openclaw");case"qoder":return t.QODER_CONFIG_DIR?x(t.QODER_CONFIG_DIR):S.join(n,".qoder");default:return t.CLAUDE_CONFIG_DIR?x(t.CLAUDE_CONFIG_DIR):S.join(n,".claude")}}var De={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 Z({runtime:e,isGlobal:n,cwd:t}){if(n)return me(e);if(e==="cline")return t;let o=De[e]??".claude";return S.join(t,o)}var nt={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 yn(e){let n=Zn.homedir();return e===n?"~":e.startsWith(`${n}${et.sep}`)?`~${e.slice(n.length)}`:e}function tt(e){let n=De[e];return n?`./${n}`:"./"}var ye=F.map((e,n)=>({choice:String(n+1),runtime:e,label:nt[e]??e})),ot=String(ye.length+1);function hn(e){return e.filter((n,t)=>e.indexOf(n)===t)}function st(e,n,t){return Math.max(n,Math.min(t,e))}function it(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 rt(){return ye.map(e=>{let n=yn(me(e.runtime));return{value:e.runtime,label:e.label,description:n,selectedSuffix:"selected"}})}function lt(e){let n=hn(e.map(o=>yn(me(o)))).join(", "),t=hn(e.map(o=>tt(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 Cn({message:e,options:n,selected:t=[],multiple:o=!0,pageSize:i=15,validate:r=a=>a.length>0,transform:s=(a=>a)}){return{message:e,options:n,selected:t.filter((l,c)=>t.indexOf(l)===c),multiple:o,pageSize:i,search:"",cursor:0,error:"",visibleOptions(){let l=this.search.trim().toLowerCase();return l?this.options.filter(c=>c.label.toLowerCase().includes(l)||c.value.toLowerCase().includes(l)):this.options},move(l){let c=this.visibleOptions();this.cursor=st(this.cursor+l,0,Math.max(0,c.length-1)),this.error=""},toggle(){let l=this.visibleOptions()[this.cursor];l&&(this.multiple?this.selected.includes(l.value)?this.selected=this.selected.filter(c=>c!==l.value):this.selected=[...this.selected,l.value]:this.selected=[l.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(l){this.search+=l,this.cursor=0,this.error=""},confirm(){let l=r(this.selected);if(l!==!0){this.error=typeof l=="string"?l:"Select at least one option";return}return s(this.selected)}}}function jn(e={}){return Cn({message:`Which runtime(s) would you like to install for? (${ye.length} available)`,options:rt(),selected:["claude"],multiple:!0,pageSize:e.pageSize??15,transform:n=>n})}function Sn(e,n={}){return Cn({message:"Where would you like to install?",options:lt(e),selected:["global"],multiple:!1,pageSize:n.pageSize??15,transform:t=>t[0]!=="local"})}function he(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)),a=Math.min(s+e.pageSize,n.length),l=n.slice(s,a);for(let c=0;c<l.length;c++){let u=l[c],R=s+c===e.cursor,b=t.has(u.value),I=R?">":" ",M=b?"[x]":"[ ]",V=u.description?` (${u.description})`:"",G=b?` (${u.selectedSuffix??"selected"})`:V;r.push(` ${I} ${M} ${u.label}${G}`)}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 at(){return he(jn())}function ct(e){let t=((e==null?"":String(e)).trim()||"1").split(/[\s,]+/).filter(Boolean);if(t.includes(ot))return F.slice();let o=[],i=new Set,r=new Map(ye.map(s=>[s.choice,s.runtime]));for(let s of t){let a=r.get(s);!a||i.has(a)||(i.add(a),o.push(a))}return o.length?o:["claude"]}function ut(e){return he(Sn(e))}function ft(e){return((e==null?"":String(e)).trim()||"1")!=="2"}var $e;function bn(e){return process.stdout.write(e),$e||($e=Xn.readFileSync(0,"utf8").split(/\r?\n/)),$e.shift()??""}function xn(e){return process.env.FRONTEND_CRAFT_FORCE_INTERACTIVE==="1"&&!process.stdin.isTTY?Promise.resolve(bn(e)):new Promise(n=>{let t=ge.createInterface({input:process.stdin,output:process.stdout});t.question(e,o=>{t.close(),n(o)}),t.on("close",()=>n(""))})}async function In(e){return process.env.FRONTEND_CRAFT_FORCE_INTERACTIVE==="1"&&!process.stdin.isTTY?bn(`${he(e)}
|
|
37
|
+
`):new Promise(n=>{let t=process.stdin,o=process.stdout,i=t.isRaw,r=0;function s(){r>0&&(ge.moveCursor(o,0,-r),ge.clearScreenDown(o));let c=he(e);o.write(c),o.write(`
|
|
38
|
+
`),r=c.split(`
|
|
39
|
+
`).length}function a(){t.off("keypress",l),t.isTTY&&t.setRawMode(!!i),t.pause()}function l(c,u){if(u?.ctrl&&u.name==="c"){a(),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&&(a(),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=it(u);g&&e.type(g)}s()}ge.emitKeypressEvents(t),t.isTTY&&t.setRawMode(!0),t.resume(),t.on("keypress",l),s()})}async function vn(){if(process.stdin.isTTY){let e=await In(jn());return Array.isArray(e)?e:["claude"]}return console.log(`${at()}
|
|
41
|
+
`),ct(await xn("Choice [1]: "))}async function kn(e){if(process.stdin.isTTY){let n=await In(Sn(e));return typeof n=="boolean"?n:!0}return console.log(`${ut(e)}
|
|
42
|
+
`),ft(await xn("Choice [1]: "))}var Ce={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 wn(e){let n=["Runtime","Tier","Skills","Agents","Commands","Hooks","Rules","Templates","MCP","Reports","Init"],t=e.map(r=>{let s=Ce[r];if(!s)throw new Error(`Missing capability declaration for runtime: ${r}`);return[r,s.tier,W(s.skills),W(s.agents),W(s.commands),W(s.hooks),W(s.rules),W(s.templates),W(s.mcp),W(s.reports),s.init]}),o=n.map((r,s)=>Math.max(r.length,...t.map(a=>a[s].length))),i=r=>r.map((s,a)=>s.padEnd(o[a])).join(" ").trimEnd();return[i(n),...t.map(i)].join(`
|
|
43
|
+
`)}function W(e){return e?"yes":"no"}import Rn from"node:fs";import ee from"node:path";import{fileURLToPath as Dn}from"node:url";function $n(e=import.meta.url){let n=ee.dirname(Dn(e));for(;;){if(Rn.existsSync(ee.join(n,"package.json"))&&Rn.existsSync(ee.join(n,"skills")))return n;let t=ee.dirname(n);if(t===n)return ee.resolve(ee.dirname(Dn(e)),"../..");n=t}}import ne from"node:fs";import On from"node:os";import T from"node:path";function je({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 a=Z({runtime:r,isGlobal:s==="global",cwd:e}),l=le(a),c=T.resolve(l);if(i.has(c))continue;i.add(c);let u=xe(l);u&&(u.runtime!==r||u.scope!==s||o.push({runtime:r,scope:s,baseDir:a,manifestPath:l,manifest:u}))}return o}function Oe({install:e,cwd:n,dryRun:t,force:o}){let i={removed:[],skipped:[],missing:[]},r=new Set;for(let s of e.manifest.files){let a=dt({filePath:s.path,root:s.root??"baseDir",baseDir:e.baseDir,cwd:n});if(!a)continue;if(!ne.existsSync(a)){i.missing.push(s.path);continue}let l=Ie(a)!==s.hash;if(l&&!o){i.skipped.push(s.path);continue}i.removed.push({path:s.path,modified:l}),r.add(T.dirname(a)),t||ne.rmSync(a,{force:!0})}return!t&&i.skipped.length===0&&(ne.rmSync(e.manifestPath,{force:!0}),pt([...r],[e.baseDir,n,On.homedir()])),i}function dt({filePath:e,root:n,baseDir:t,cwd:o}){let i=n==="baseDir"?t:n==="cwd"?o:On.homedir(),r=T.resolve(i),s=T.resolve(r,e),a=T.relative(r,s);if(!(a.startsWith("..")||T.isAbsolute(a)))return s}function pt(e,n){let t=n.map(o=>T.resolve(o));for(let o of e.sort((i,r)=>r.length-i.length)){let i=T.resolve(o);for(;mt(i,t)&&!t.includes(i)&&!(!ne.existsSync(i)||ne.readdirSync(i).length>0);)ne.rmdirSync(i),i=T.dirname(i)}}function mt(e,n){return n.some(t=>{let o=T.relative(t,e);return o!==""&&!o.startsWith("..")&&!T.isAbsolute(o)})}import N from"node:fs";import Ne from"node:os";import w from"node:path";function Fe({claudeConfigDir:e=_e(),currentVersion:n}){let t=w.join(e,"plugins","cache","frontend-craft","frontend-craft"),o=ht(e),i=gt({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(a=>({...a,shouldDelete:s&&a.shouldDelete,reasons:s?a.reasons:["metadata unavailable"]})),canDelete:s,warning:r}}function _n({claudeConfigDir:e=_e(),currentVersion:n,dryRun:t=!1}){let o=Fe({claudeConfigDir:e,currentVersion:n}),i=[];if(o.canDelete)for(let r of o.entries)r.shouldDelete&&(t||N.rmSync(r.path,{recursive:!0,force:!0}),t||i.push(r));return{...o,deleted:i}}function Me({claudeConfigDir:e=_e(),cwd:n=process.cwd()}={}){let t=yt(e),o=[Nn(w.join(n,".claude","frontend-craft.manifest.json"),"local"),Nn(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 re(e){let n=["install sources:"];if(e.native.length===0&&e.cli.length===0)return n.push(" none detected"),n.join(`
|
|
44
|
+
`);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 Se(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
|
+
`);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 Tn(e,n){if(n)return Se(e,"dry-run");let t=[Se(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(`
|
|
48
|
+
`)}function _e(){return bt(process.env.CLAUDE_CONFIG_DIR??w.join(Ne.homedir(),".claude"))}function gt({cacheDir:e,currentInstallPaths:n,currentVersion:t}){if(!N.existsSync(e))return[];let o=new Set(n.map(Mn));return N.readdirSync(e,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>{let r=w.join(e,i.name),s=jt(r),a=N.existsSync(w.join(r,"dist")),l=N.existsSync(w.join(r,".orphaned_at")),c=o.has(Mn(r)),u=[];return l&&u.push("orphaned"),a||u.push("missing dist"),s&&St(s,t)<0&&u.push(`package ${s} < ${t}`),{version:i.name,path:r,isCurrent:c,hasDist:a,orphaned:l,packageVersion:s,reasons:u,shouldDelete:!c&&u.length>0}}).sort((i,r)=>i.version.localeCompare(r.version,void 0,{numeric:!0}))}function ht(e){let n=w.join(e,"plugins","installed_plugins.json");if(!N.existsSync(n))return{paths:[],warning:`missing ${n}; refusing to delete cache entries`};try{let t=JSON.parse(N.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 yt(e){let n=w.join(e,"plugins","installed_plugins.json");if(!N.existsSync(n))return[];try{let t=JSON.parse(N.readFileSync(n,"utf8"));return Object.entries(t.plugins??{}).flatMap(([o,i])=>Ct(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 Ct(e){return e==="frontend-craft@bovinphang/frontend-craft"||e==="frontend-craft@frontend-craft"||e.startsWith("frontend-craft@")}function Nn(e,n){if(N.existsSync(e))try{let t=JSON.parse(N.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 jt(e){let n=w.join(e,"package.json");if(N.existsSync(n))try{let t=JSON.parse(N.readFileSync(n,"utf8"));return typeof t.version=="string"?t.version:void 0}catch{return}}function St(e,n){let t=Fn(e),o=Fn(n);for(let i=0;i<3;i+=1)if(t[i]!==o[i])return t[i]-o[i];return 0}function Fn(e){let n=e.match(/^(\d+)\.(\d+)\.(\d+)/);return n?[Number(n[1]),Number(n[2]),Number(n[3])]:[0,0,0]}function bt(e){return e==="~"?Ne.homedir():e.startsWith("~/")||e.startsWith("~\\")?w.join(Ne.homedir(),e.slice(2)):e}function Mn(e){let n=w.resolve(e);return process.platform==="win32"?n.toLowerCase():n}function Ee(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 It(e){let n=null,t=!1,o=!1,i=!1,r=!1,s=!1,a=[];for(let l of e)l==="--global"||l==="-g"?(t=!0,n="global"):l==="--local"||l==="-l"?(o=!0,n="local"):l==="--dry-run"?i=!0:l==="--force"?r=!0:l==="--all"?s=!0:l.startsWith("-")||a.push(l);return{runtime:a[0],installLocation:n,dryRun:i,force:r,all:s,hasGlobal:t,hasLocal:o}}function Te(){console.log(`frontend-craft - universal installer
|
|
49
|
+
|
|
50
|
+
Usage:
|
|
51
|
+
frontend-craft install <runtime> [options]
|
|
52
|
+
frontend-craft install --all [options]
|
|
53
|
+
frontend-craft install
|
|
54
|
+
frontend-craft init [runtime] [options]
|
|
55
|
+
fec init [runtime] [options]
|
|
56
|
+
frontend-craft update [runtime] [options]
|
|
57
|
+
frontend-craft upgrade [runtime] [options]
|
|
58
|
+
frontend-craft uninstall|remove [runtime] [options]
|
|
59
|
+
frontend-craft list
|
|
60
|
+
frontend-craft matrix
|
|
61
|
+
frontend-craft doctor <runtime>
|
|
62
|
+
frontend-craft doctor claude --fix-cache [--dry-run]
|
|
63
|
+
frontend-craft sync-metadata --check
|
|
64
|
+
frontend-craft version
|
|
65
|
+
|
|
66
|
+
Options:
|
|
67
|
+
--global, -g Install to tool global config directory
|
|
68
|
+
--local, -l Install to this project only
|
|
69
|
+
--dry-run Show actions without writing files
|
|
70
|
+
--force Uninstall: remove modified managed files (does not override Claude Marketplace)
|
|
71
|
+
--all Install for every supported runtime
|
|
72
|
+
|
|
73
|
+
Notes:
|
|
74
|
+
init is an alias for install --local unless --global is explicitly provided.
|
|
75
|
+
update without a runtime refreshes discovered frontend-craft manifests.
|
|
76
|
+
uninstall/remove deletes manifest-managed files and skips modified files unless --force is provided.
|
|
77
|
+
/fec-init is the in-assistant slash command; fec init is the terminal CLI command.
|
|
78
|
+
|
|
79
|
+
Runtimes:
|
|
80
|
+
${F.join(", ")}
|
|
81
|
+
`)}function Pn(e){let n=e[0];return n==null||["--dry-run","--all","--global","-g","--local","-l"].includes(n)}async function Un(e){let n=Pn(e)?"install":e[0],t=Pn(e)?e:e.slice(1),o=n==="init",i=$n(import.meta.url);if(n==="version"||n==="-v"||n==="--version"){console.log(Ee(i));return}if(n==="list"){F.forEach(h=>console.log(h));return}if(n==="matrix"){console.log(wn(F));return}if(n==="doctor"){let h=t[0]??"claude",_=t.includes("--global")||t.includes("-g"),P=t.includes("--fix-cache"),q=t.includes("--dry-run"),B=process.cwd(),L=Z({runtime:h,isGlobal:_,cwd:B}),be=Ce[h];if(!be){console.error(`Unknown runtime: ${h}`),process.exitCode=1;return}console.log($t({runtime:h,baseDir:L,cwd:B,cap:be,pluginRoot:i,fixCache:P,dryRun:q,isGlobal:_}));return}if(n==="sync-metadata"){let h=t.includes("--check"),_=Tt(i);if(_.length>0){for(let P of _)console.error(P);process.exitCode=1;return}console.log(h?"metadata is synchronized":"metadata is synchronized; no changes needed");return}if(n==="help"||n==="-h"||n==="--help"){Te();return}let r=n==="update"||n==="upgrade"?"update":"install";if(n!=="install"&&n!=="init"&&n!=="update"&&n!=="upgrade"&&n!=="uninstall"&&n!=="remove"){console.error(`Unknown command: ${n}`),Te(),process.exitCode=1;return}if(t.some(h=>h==="help"||h==="--help"||h==="-h")){Te();return}let{runtime:s,installLocation:a,dryRun:l,force:c,all:u,hasGlobal:g,hasLocal:R}=It(t),b=a??(o?"local":null);if(g&&R){console.error("--global and --local cannot be used together."),process.exitCode=1;return}let I=process.cwd();if(n==="uninstall"||n==="remove"){let h=Gn(R,g),P=je({cwd:I,runtimes:s?[s]:u?F:void 0,scopes:h});if(s&&!pe[s]){console.error(`Unknown runtime: ${s}`),process.exitCode=1;return}if(P.length===0){console.log(Ln("uninstall",s,h));return}for(let q of P){console.log(`Uninstalling frontend-craft for "${q.runtime}" -> ${q.baseDir}${q.scope==="global"?" (global)":""}`);let B=Oe({install:q,cwd:I,dryRun:l,force:c});for(let L of B.removed)console.log(`${l?"[dry-run] would remove":"Removed"}${L.modified?" modified file":" file"}: ${L.path}`);for(let L of B.skipped)console.log(`Skipped modified file: ${L}`);for(let L of B.missing)console.log(`Missing file: ${L}`);l&&B.skipped.length===0&&console.log(`[dry-run] would remove manifest: ${q.manifestPath}`)}return}let M=!!process.stdin.isTTY||process.env.FRONTEND_CRAFT_FORCE_INTERACTIVE==="1";if(r==="update"&&!s){let h=Gn(R,g),_=je({cwd:I,runtimes:u?F:void 0,scopes:h});if(_.length===0){console.log(Ln("update",void 0,h));return}for(let P of _)await En({rt:P.runtime,mode:r,isGlobal:P.scope==="global",baseDir:P.baseDir,pluginRoot:i,cwd:I,dryRun:l});return}let V=u?F:s?[s]:[];V.length||(M?V=await vn():(console.log("Non-interactive terminal detected, defaulting to claude runtime."),V=["claude"]));let G;b==="global"?G=!0:b==="local"?G=!1:M?G=await kn(V):(console.log("Non-interactive terminal detected, defaulting to global install."),G=!0);for(let h of V){if(!pe[h]){console.error(`Unknown runtime: ${h}`),process.exitCode=1;continue}let _=Z({runtime:h,isGlobal:G,cwd:I});await En({rt:h,mode:r,isGlobal:G,baseDir:_,pluginRoot:i,cwd:I,dryRun:l,force:c,canPrompt:M})}}async function En({rt:e,mode:n,isGlobal:t,baseDir:o,pluginRoot:i,cwd:r,dryRun:s,force:a,canPrompt:l}){let c=await vt({rt:e,mode:n,isGlobal:t,cwd:r,dryRun:s,force:!!a,canPrompt:!!l});if(!c)return;c.redirect&&(t=c.redirect.isGlobal,o=c.redirect.baseDir,n="update");let u={pluginRoot:i,cwd:r,runtime:e,isGlobal:t,baseDir:o,dryRun:s,mode:n,capabilities:Ce[e]};n==="install"?(console.log(`Installing frontend-craft for "${e}" -> ${o}${t?" (global)":""}`),!s&&m.existsSync(le(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||Ae({baseDir:o,cwd:r,mode:n,packageVersion:Ee(i),runtime:e,isGlobal:t});try{await pe[e](u),s||Ge()}catch(g){throw s||Le(),g}}async function vt({rt:e,mode:n,isGlobal:t,cwd:o,dryRun:i,force:r,canPrompt:s}){if(e!=="claude")return{};let a=Me({cwd:o});if(a.native.length>0){console.log("Claude Code Marketplace install detected for frontend-craft."),console.log(re(a)),console.log("Update frontend-craft through Claude Code Marketplace. CLI install/update is disabled while Marketplace is active."),process.exitCode=1;return}let l=t?"cli-global":"cli-local",c=a.cli.filter(I=>Pe(I)!==l);if(c.length===0)return a.hasMultipleActiveSources&&console.log(re(a)),{};let u=c[0],g=Pe(u);if(console.log(`${J(g)} install detected for frontend-craft.`),console.log(re(a)),i){console.log(`[dry-run] resolve the existing ${J(g)} source before using ${J(l)}.`),process.exitCode=1;return}if(!s){wt(g,l),process.exitCode=1;return}if(await Rt(g,l)==="switch"){if(!kt({installs:c,cwd:o,dryRun:i,force:r})){process.exitCode=1;return}return{}}let b=g==="cli-global";return{redirect:{isGlobal:b,baseDir:Z({runtime:"claude",isGlobal:b,cwd:o})}}}function kt({installs:e,cwd:n,dryRun:t,force:o}){for(let i of e){let r=je({cwd:n,runtimes:["claude"],scopes:[i.scope]})[0];if(!r)continue;console.log(`Uninstalling existing ${J(Pe(i))} install before switching source.`);let s=Oe({install:r,cwd:n,dryRun:t,force:o});for(let a of s.removed)console.log(`${t?"[dry-run] would remove":"Removed"}${a.modified?" modified file":" file"}: ${a.path}`);for(let a of s.skipped)console.log(`Skipped modified file: ${a}`);for(let a of s.missing)console.log(`Missing file: ${a}`);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 wt(e,n){let t=An(e),o=An(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 Rt(e,n){return console.log("Choose how to resolve the Claude CLI install source conflict:"),console.log(` 1. Keep ${J(e)} and update it`),console.log(` 2. Uninstall ${J(e)} and install ${J(n)}`),(await Dt("Choice [1]: ")).trim()==="2"?"switch":"keep"}function Dt(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=xt.createInterface({input:process.stdin,output:process.stdout});t.question(e,o=>{t.close(),n(o)}),t.on("close",()=>n(""))})}function Pe(e){return e.scope==="global"?"cli-global":"cli-local"}function J(e){return e==="marketplace"?"Claude Code Marketplace":e==="cli-global"?"Claude CLI global":"Claude CLI local"}function An(e){return e==="cli-global"?"--global":"--local"}function Gn(e,n){return e?["local"]:n?["global"]:["local","global"]}function Ln(e,n,t){return`No frontend-craft installs found${n?` for "${n}"`:""} to ${e} (${t.join(", ")}).`}function $t({runtime:e,baseDir:n,cwd:t,cap:o,pluginRoot:i,fixCache:r,dryRun:s,isGlobal:a}){let l=[`frontend-craft doctor: ${e}`,`baseDir: ${n}`,`tier: ${o.tier}`];if(l.push(`skills: ${te(Ot(e,n,t),o.skills)}`),l.push(`agents: ${te(m.existsSync(d.join(n,"agents")),o.agents)}`),l.push(`commands: ${te(Nt(e,n),o.commands)}`),l.push(`hooks: ${te(Ft(e,n),o.hooks)}`),l.push(`rules: ${te(Mt(e,n),o.rules&&!a)}`),l.push(`templates: ${te(_t(e,n,t),o.templates)}`),e==="claude"){let c=Ee(i);l.push(re(Me({cwd:t}))),r?l.push(Tn(_n({currentVersion:c,dryRun:s}),s)):l.push(Se(Fe({currentVersion:c})))}return l.join(`
|
|
82
|
+
`)}function te(e,n){return n?e?"ok":"missing":"not expected"}function Ot(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 Nt(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 Ft(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 Mt(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 _t(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 Tt(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),R=JSON.parse(m.readFileSync(g,"utf8")),b=u.split(".").reduce((I,M)=>I?.[Number.isNaN(Number(M))?M:Number(M)],R);b!==t.version&&n.push(`${c} ${u} is ${b}, 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,a=m.readdirSync(d.join(e,"agents")).filter(c=>c.endsWith(".md")).length,l=m.readFileSync(d.join(e,".claude-plugin","marketplace.json"),"utf8");return l.includes(`${a} agents`)||n.push(`marketplace description must mention ${a} agents`),l.includes(`${s} skills`)||n.push(`marketplace description must mention ${s} skills`),l.includes(`${r} commands`)||n.push(`marketplace description must mention ${r} commands`),n}Un(process.argv.slice(2)).catch(e=>{console.error(e),process.exit(1)});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import I from"node:fs";import f from"node:path";import{fileURLToPath as R}from"node:url";import o from"node:fs";import d from"node:os";import a from"node:path";function w({claudeConfigDir:e=S(),currentVersion:n}){let t=a.join(e,"plugins","cache","frontend-craft","frontend-craft"),r=b(e),s=j({cacheDir:t,currentInstallPaths:r.paths,currentVersion:n}),i=r.warning,l=!i&&r.paths.length>0;return{claudeConfigDir:e,cacheDir:t,currentInstallPaths:r.paths,entries:s.map(c=>({...c,shouldDelete:l&&c.shouldDelete,reasons:l?c.reasons:["metadata unavailable"]})),canDelete:l,warning:i}}function v({claudeConfigDir:e=S(),currentVersion:n,dryRun:t=!1}){let r=w({claudeConfigDir:e,currentVersion:n}),s=[];if(r.canDelete)for(let i of r.entries)i.shouldDelete&&(t||o.rmSync(i.path,{recursive:!0,force:!0}),t||s.push(i));return{...r,deleted:s}}function h(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(`
|
|
2
|
+
`);for(let r of e.entries){let s=r.isCurrent?"current install":r.reasons.length?r.reasons.join(", "):"healthy",i=n==="dry-run"&&r.shouldDelete?"would delete":n==="fix"&&r.shouldDelete?"delete":"keep";t.push(` ${i} ${r.version}: ${s}`)}return t.join(`
|
|
3
|
+
`)}function y(e,n){if(n)return h(e,"dry-run");let t=[h(e,"fix")];for(let r of e.deleted)t.push(` deleted ${r.version}: ${r.path}`);return e.deleted.length===0&&t.push(" deleted: none"),t.join(`
|
|
4
|
+
`)}function S(){return k(process.env.CLAUDE_CONFIG_DIR??a.join(d.homedir(),".claude"))}function j({cacheDir:e,currentInstallPaths:n,currentVersion:t}){if(!o.existsSync(e))return[];let r=new Set(n.map(m));return o.readdirSync(e,{withFileTypes:!0}).filter(s=>s.isDirectory()).map(s=>{let i=a.join(e,s.name),l=x(i),c=o.existsSync(a.join(i,"dist")),p=o.existsSync(a.join(i,".orphaned_at")),g=r.has(m(i)),u=[];return p&&u.push("orphaned"),c||u.push("missing dist"),l&&P(l,t)<0&&u.push(`package ${l} < ${t}`),{version:s.name,path:i,isCurrent:g,hasDist:c,orphaned:p,packageVersion:l,reasons:u,shouldDelete:!g&&u.length>0}}).sort((s,i)=>s.version.localeCompare(i.version,void 0,{numeric:!0}))}function b(e){let n=a.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")),r=(t.plugins?.["frontend-craft@bovinphang/frontend-craft"]??t.plugins?.["frontend-craft@frontend-craft"]??[]).map(s=>s.installPath).filter(s=>typeof s=="string"&&s.length>0).map(s=>a.resolve(s));return r.length===0?{paths:r,warning:`missing frontend-craft plugin entry in ${n}; refusing to delete cache entries`}:{paths:r}}catch{return{paths:[],warning:`invalid ${n}; refusing to delete cache entries`}}}function x(e){let n=a.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 P(e,n){let t=C(e),r=C(n);for(let s=0;s<3;s+=1)if(t[s]!==r[s])return t[s]-r[s];return 0}function C(e){let n=e.match(/^(\d+)\.(\d+)\.(\d+)/);return n?[Number(n[1]),Number(n[2]),Number(n[3])]:[0,0,0]}function k(e){return e==="~"?d.homedir():e.startsWith("~/")||e.startsWith("~\\")?a.join(d.homedir(),e.slice(2)):e}function m(e){let n=a.resolve(e);return process.platform==="win32"?n.toLowerCase():n}try{let e=$(),n=v({currentVersion:e});(n.deleted.length>0||n.warning)&&console.error(y(n,!1))}catch(e){let n=e instanceof Error?e.message:String(e);console.error(`[frontend-craft] Claude cache cleanup warning: ${n}`)}function $(){let e=R(import.meta.url),n=f.resolve(f.dirname(e),"..",".."),t=f.join(n,"package.json"),r=JSON.parse(I.readFileSync(t,"utf8"));return typeof r.version=="string"?r.version:"0.0.0"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{stdin as e}from"node:process";import{existsSync as i}from"node:fs";import{execFileSync as c}from"node:child_process";var o=[];for await(let t of e)o.push(t);var r=Buffer.concat(o).toString(),s="";try{let t=JSON.parse(r);s=t?.tool_input?.file_path??t?.tool_input?.filePath??""}catch{process.exit(0)}(!s||!i(s))&&process.exit(0);var n=/\.(js|jsx|ts|tsx|vue|css|scss|less|json|md|html)$/;n.test(s)||process.exit(0);try{let t=process.platform==="win32"?"npx.cmd":"npx";c(t,["prettier","--write",s],{stdio:"ignore"})}catch{}process.exit(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{execSync as e}from"node:child_process";import{platform as i}from"node:os";process.stdin.resume();process.stdin.on("data",()=>{});var o=i();try{o==="darwin"?e(`osascript -e 'display notification "Claude Code 浠诲姟瀹屾垚" with title "Claude Code"'`,{stdio:"ignore"}):o==="linux"?e('notify-send "Claude Code" "Claude Code 浠诲姟瀹屾垚"',{stdio:"ignore"}):o==="win32"&&e(`powershell -NoProfile -Command "[console]::beep(600,300); Write-Host 'Claude Code 浠诲姟瀹屾垚'"`,{stdio:"ignore"})}catch{}process.exit(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as i,readFileSync as n}from"node:fs";import{execSync as o}from"node:child_process";try{let e=function(t){if(c[t])try{o(`${s} run ${t}`,{stdio:["ignore","pipe","pipe"],timeout:12e4})}catch{r=!0}};a=e,process.stdin.resume(),process.stdin.on("data",()=>{}),i("package.json")||process.exit(0);let p=process.env.FRONTEND_CRAFT_VALIDATION_MODE==="blocking",r=!1,c={};try{c=JSON.parse(n("package.json","utf-8")).scripts??{}}catch{process.exit(0)}let s="npm";i("pnpm-lock.yaml")?s="pnpm":i("yarn.lock")&&(s="yarn"),e("lint"),c["type-check"]?e("type-check"):e("typecheck"),e("test"),e("build"),p&&r&&process.exit(1)}catch{process.env.FRONTEND_CRAFT_VALIDATION_MODE==="blocking"&&process.exit(1)}var a;process.exit(0);
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{stdin as i}from"node:process";var t=[];for await(let s of i)t.push(s);var r=Buffer.concat(t).toString(),e="";try{e=JSON.parse(r)?.tool_input?.command??""}catch{process.exit(0)}e||process.exit(0);var n=[/rm\s+-rf\s+\//i,/rm\s+-rf\s+\/\*/i,/\bremove-item\b.*\b-recurse\b.*\b-force\b.*(?:[a-z]:\\|\/|~)/i,/\brmdir\b.*\/s\b.*\/q\b/i,/\bdel\b.*\/[fsq]\b/i,/\bchmod\b\s+-R\s+777\b/i,/\bchown\b\s+-R\b/i,/git\s+push\s+.*--force/i,/\bgit\s+clean\b.*-[^\s]*f[^\s]*d/i,/\bmkfs\b/i,/\bdd\s+if=/i,/\bshutdown\b/i,/\breboot\b/i,/curl\s+.*\|\s*sh/i,/wget\s+.*\|\s*sh/i,/\biwr\b.*\|\s*iex\b/i,/\binvoke-webrequest\b.*\|\s*invoke-expression\b/i,/\b(printenv|env|set)\b.*(TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY)/i,/\bcat\b.*\.(env|npmrc|pypirc)\b/i,/\bnpm\s+run\b.*(?:postinstall|preinstall|prepare).*(?:curl|wget|iwr|iex|rm\s+-rf)/i,/DROP\s+TABLE/i,/DROP\s+DATABASE/i,/format\s+c:/i,/>\s*\/dev\/sda/i];for(let s of n)s.test(e)&&(process.stderr.write(`Blocked potentially dangerous command by frontend-craft: matched pattern '${s}'`),process.exit(2));var b=[/\b(npm|pnpm|yarn|bun)\s+(run\s+)?dev\b/i,/\b(npm|pnpm|yarn|bun)\s+(run\s+)?(test|build)\b/i,/\b(vitest|playwright|cypress)\b/i];b.some(s=>s.test(e))&&process.stderr.write(`frontend-craft note: long-running frontend commands are easier to debug when their logs stay visible in a persistent terminal or CI artifact.
|
|
2
|
+
`);process.exit(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as a,readFileSync as c}from"node:fs";process.stdin.resume();process.stdin.on("data",()=>{});a("package.json")||process.exit(0);var r="unknown";try{let t=JSON.parse(c("package.json","utf-8")),e={...t.dependencies,...t.devDependencies},n=[];(e.vue||e.nuxt)&&n.push("Vue "+(e.vue||e.nuxt)),(e.react||e.next)&&n.push("React "+(e.react||e.next)),e["@angular/core"]&&n.push("Angular "+e["@angular/core"]),r=n.join(", ")||"unknown"}catch{}var s="npm";a("pnpm-lock.yaml")?s="pnpm":a("yarn.lock")?s="yarn":a("bun.lockb")&&(s="bun");r!=="unknown"&&process.stdout.write(`[frontend-craft] Framework: ${r} | Package manager: ${s}`);process.exit(0);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Example Prompts
|
|
2
|
+
|
|
3
|
+
Use these prompts after installing `frontend-craft` in any supported runtime. You do not need to memorize internal skill, command, or agent names; describe the outcome you want and include useful context such as file paths, framework, failing commands, design links, or acceptance criteria.
|
|
4
|
+
|
|
5
|
+
Each example follows the same shape:
|
|
6
|
+
|
|
7
|
+
- **Scenario**: when to use it.
|
|
8
|
+
- **Prompt**: text you can paste or adapt.
|
|
9
|
+
- **Best for**: the `frontend-craft` capability most likely to help.
|
|
10
|
+
- **Expected output**: what the assistant should produce.
|
|
11
|
+
- **Notes**: extra context that improves the result.
|
|
12
|
+
|
|
13
|
+
## Getting Started
|
|
14
|
+
|
|
15
|
+
| Scenario | Prompt | Best for | Expected output | Notes |
|
|
16
|
+
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------------------------------------------------------------------------------- | ---------------------------------------- |
|
|
17
|
+
| Initialize project rules | "Initialize this repository with the frontend-craft project templates for my current runtime. Ask before overwriting existing files." | `/fec-init` | Runtime config, rules, and project guidance installed or a clear overwrite plan. | Works best from the target project root. |
|
|
18
|
+
| Pick a runtime install path | "I want to use frontend-craft with Codex and Claude Code on this machine. Explain whether I should install locally or globally, then show the exact commands." | runtime docs | A short recommendation and install commands. | Mention team/shared vs personal use. |
|
|
19
|
+
| Learn how to ask | "Show me five frontend-craft prompts for reviewing, building, testing, debugging, and design-to-code work in this repo." | docs guidance | A short prompt set tailored to the detected project. | Good first prompt after install. |
|
|
20
|
+
| Confirm available capabilities | "Inspect this repo and summarize which frontend-craft commands, skills, agents, hooks, and MCP templates are available." | `fec-doc-sync`, runtime docs | Capability summary grounded in installed files. | Useful after upgrades. |
|
|
21
|
+
|
|
22
|
+
## Review And Quality
|
|
23
|
+
|
|
24
|
+
| Scenario | Prompt | Best for | Expected output | Notes |
|
|
25
|
+
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
26
|
+
| Review recent changes | "Review my recent changes before merge. Focus on architecture, type safety, rendering behavior, styles, accessibility, and missing tests. Put findings first." | `fec-code-review`, `fec-code-reviewer`, `/fec-review` | Severity-ordered review with file references and test gaps. | Add branch or diff range if needed. |
|
|
27
|
+
| PR readiness review | "Review `src/features/checkout/` as if this is a PR. Call out blockers, risky assumptions, and what must be tested before merge." | `fec-code-reviewer` | Merge readiness assessment and structured report. | Include PR link if the runtime can access it. |
|
|
28
|
+
| TypeScript专项 review | "Audit the changed `.ts` and `.tsx` files for unsafe types, async bugs, over-wide interfaces, stale derived state, and non-idiomatic React/TypeScript." | `fec-typescript-reviewer` | TypeScript-focused findings, usually report-only. | Best when JS/TS changes dominate. |
|
|
29
|
+
| Type contract review | "Review the API DTOs, component props, generic helpers, and type guards in `src/features/billing/` for unsound assertions, over-wide types, and missing runtime narrowing." | `fec-typescript-type-safety`, `fec-typescript-reviewer` | Type-boundary findings with safer models and type-test suggestions. | Good for SDK, design-system, or API-heavy changes. |
|
|
30
|
+
| Security review | "Audit `src/lib/auth.ts`, API clients, and any user HTML rendering for XSS, token leakage, unsafe storage, CSRF assumptions, and dangerous DOM APIs." | `fec-security-review`, `fec-security-reviewer` | Security findings ranked by severity with concrete fixes. | Include auth model and storage constraints. |
|
|
31
|
+
| Accessibility review | "Check `src/components/ConfirmDialog.tsx` for focus trapping, keyboard flow, labels, ARIA usage, screen-reader behavior, touch targets, and WCAG 2.2 AA issues." | `fec-accessibility-check` | A11y findings and implementation guidance. | Provide screenshots for visual focus issues. |
|
|
32
|
+
| Performance review | "Analyze dashboard performance with evidence: Core Web Vitals, bundle size, render hotspots, data waterfalls, memory leaks, and a realistic performance budget." | `fec-performance-optimization`, `fec-performance-optimizer` | Performance report with baseline evidence, priorities, verification commands, and targeted fixes. | Include profiles, Lighthouse output, traces, or the slow user flow if available. |
|
|
33
|
+
| UI fidelity review | "Compare the implemented settings page against the supplied screenshot/design link and list layout, spacing, typography, state, and responsive mismatches." | `fec-ui-checker` | UI fidelity report with actionable fixes. | Attach screenshot or design source. |
|
|
34
|
+
|
|
35
|
+
## Planning And Architecture
|
|
36
|
+
|
|
37
|
+
| Scenario | Prompt | Best for | Expected output | Notes |
|
|
38
|
+
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
|
|
39
|
+
| Plan a feature | "Before coding, plan the account billing feature: route structure, component boundaries, data flow, state ownership, validation flow, and rollout risks." | `/fec-plan`, `fec-architect` | Architecture proposal and implementation plan. | Give acceptance criteria and constraints. |
|
|
40
|
+
| Split a complex page | "Refactor `src/pages/Dashboard.tsx` on paper first. Propose component boundaries, hooks, state ownership, and a safe step-by-step migration." | `fec-architect`, `fec-refactor-clean` | Refactor plan with risk controls. | Ask for no code changes if you only want planning. |
|
|
41
|
+
| Test strategy | "For the checkout rewrite, map risks to static checks, unit tests, component tests, E2E, visual checks, accessibility, and security coverage." | `/fec-plan`, `fec-testing-strategy`, `fec-test-planner` | Testing matrix and priority order. | Useful before a large implementation. |
|
|
42
|
+
| Source-driven decision | "Before changing our Next.js caching approach, verify the current project code and official docs. Summarize the version assumptions, recommended pattern, migration impact, and tests needed." | `fec-source-driven-development` | Source-backed decision summary with project facts, official references, assumptions, and verification steps. | Best for framework/library behavior that may have changed. |
|
|
43
|
+
| Legacy migration | "We have a jQuery multi-page app in `public/js/legacy/`. Create a phased plan to migrate to React + TypeScript without stopping feature work." | `fec-legacy-to-modern-migration` | Migration plan, risks, milestones, compatibility strategy. | Include release cadence and legacy constraints. |
|
|
44
|
+
|
|
45
|
+
## Implementation
|
|
46
|
+
|
|
47
|
+
| Scenario | Prompt | Best for | Expected output | Notes |
|
|
48
|
+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------- |
|
|
49
|
+
| React feature | "Build a React + TypeScript user detail page that follows this repo's component, hook, route, state, and API patterns." | `fec-react-project-standard` | Code aligned with local React conventions. | Include target route and API shape. |
|
|
50
|
+
| Vue 3 feature | "Implement `Settings.vue` using Vue 3 + TypeScript conventions, Composition API, Pinia where appropriate, and existing composables." | `fec-vue3-project-standard` | Vue code matching project patterns. | Mention SSR/client-only constraints if relevant. |
|
|
51
|
+
| Next.js App Router | "Review and improve `app/(dashboard)/reports/page.tsx` for App Router data fetching, metadata, loading/error states, server/client boundaries, and actions." | `fec-nextjs-project-standard` | Next.js-specific findings or code changes. | Include route segment behavior. |
|
|
52
|
+
| Nuxt 3 page | "Build the admin reports page in Nuxt 3 with correct SSR behavior, `useFetch`/composables, middleware, and typed server routes." | `fec-nuxt-project-standard` | Nuxt implementation following conventions. | State whether route is SSR, SSG, or SPA. |
|
|
53
|
+
| Vite config | "Audit `vite.config.ts` for HMR, env variable exposure, dev proxy, build output, dependency pre-bundling, and plugin ordering." | `fec-vite-project-standard` | Vite config findings and safe edits. | Include build or dev-server symptoms. |
|
|
54
|
+
| Official-docs check | "Check whether our Vite dependency pre-bundling workaround is still needed in the installed version. Use project config and official docs before recommending removal." | `fec-source-driven-development`, `fec-vite-project-standard` | Version-aware recommendation with source notes and rollback/verification plan. | Useful before removing compatibility code. |
|
|
55
|
+
| Monorepo boundaries | "Check `apps/web` and `packages/ui` for package boundaries, workspace dependencies, build scripts, and Turborepo/Nx task graph issues." | `fec-monorepo-project-standard` | Boundary and task orchestration review. | Include package manager and workspace files. |
|
|
56
|
+
| Dependency upgrade | "Plan the Vite and Storybook upgrade in this repo: read release notes, identify breaking changes, review lockfile and peer dependency risks, and propose the validation matrix." | `fec-dependency-upgrade`, `fec-source-driven-development` | Upgrade batches, source-backed risks, affected areas, verification commands, and rollback notes. | Keep major upgrades separate from unrelated refactors. |
|
|
57
|
+
| Server-state data | "Review `src/queries/useReports.ts`: query keys, cache lifetime, invalidation, optimistic updates, error states, and suspense/loading behavior." | `fec-data-fetching` | TanStack Query/server-state guidance or implementation. | Include API volatility and UX expectations. |
|
|
58
|
+
| State ownership | "Audit dashboard state ownership: decide what belongs in URL params, TanStack Query, local component state, browser persistence, or a global store, then propose a safe migration." | `fec-state-management` | State inventory, ownership decisions, store boundaries, and verification steps. | Useful before store refactors or removing duplicated state. |
|
|
59
|
+
| API integration | "Design a typed API integration layer for checkout: client boundaries, error mapping, auth refresh, upload strategy, and whether order updates should use polling, SSE, or WebSocket." | `fec-api-integration` | API client strategy or implementation with failure states and integration checks. | Include backend ownership, auth model, and endpoint contracts. |
|
|
60
|
+
| Complex form | "Build a multi-step registration form with React Hook Form + Zod, file upload, conditional fields, async validation, and accessible errors." | `fec-form-handling` | Typed form implementation and tests if requested. | Include final payload contract. |
|
|
61
|
+
| Route protection | "Add role-based protection for `/admin`: redirect anonymous users, deny unauthorized roles, preserve return URL, and avoid flashing protected content." | `fec-route-protection` | Auth guard/middleware implementation. | Explain auth source and roles. |
|
|
62
|
+
| Browser storage | "Choose and implement safe client persistence for draft checkout data. Compare localStorage, sessionStorage, IndexedDB, and cookies for this use case." | `fec-browser-storage` | Storage recommendation and implementation. | Mention sensitive fields and retention rules. |
|
|
63
|
+
| Large list | "`ProductList` renders 20,000 rows and scrolls poorly. Add virtualization and keep keyboard navigation and dynamic row heights working." | `fec-list-virtualization` | Virtualized list implementation and performance notes. | Provide UI library constraints. |
|
|
64
|
+
| PWA | "Turn this app into an installable PWA with manifest, icons, service worker, offline fallback, cache strategy, and update prompt." | `fec-pwa-implementation` | PWA implementation and validation steps. | State whether auth/payment routes must be network-only. |
|
|
65
|
+
| Web Worker | "Move image processing off the main thread using a Web Worker and Comlink, with progress updates and cancellation." | `fec-web-workers` | Worker integration and typed messaging. | Mention browser support and file size limits. |
|
|
66
|
+
| Canvas/Three.js | "Add a WebGL shader background or Three.js product viewer with responsive sizing, WebGL2/shader error checks, accessible fallback, performance safeguards, and verification that the canvas renders." | `fec-canvas-threejs` | 3D/canvas/shader implementation and visual verification. | Include assets, shader requirements, and interaction constraints. |
|
|
67
|
+
| SVG animation | "Add reduced-motion-aware SVG micro-interactions to the hero illustration using the animation library already used in the app." | `fec-svg-animation` | SVG animation with fallback behavior. | Include motion constraints and target browsers. |
|
|
68
|
+
|
|
69
|
+
## UI And Design
|
|
70
|
+
|
|
71
|
+
| Scenario | Prompt | Best for | Expected output | Notes |
|
|
72
|
+
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
73
|
+
| Design-to-code | "Implement the UI from Figma node `123:456`. Use existing design tokens and components, match spacing and responsive states, and document assumptions." | `fec-implement-from-design`, `fec-figma-implementer` | UI code plus design implementation notes/report. | Works best with MCP credentials configured. |
|
|
74
|
+
| Screenshot-to-polish | "Polish this dashboard UI so it feels like a production SaaS tool: density, hierarchy, empty/loading/error states, responsive layout, and interaction states." | `fec-ui-design` | UI improvements and visual QA notes. | Provide screenshot or local URL if possible. |
|
|
75
|
+
| Responsive layout | "Fix this admin table for 375px, 768px, and 1440px: decide mobile column priority, container-query behavior, touch targets, safe-area handling, and overflow rules." | `fec-responsive-layout`, `fec-ui-checker` | Responsive strategy, layout changes, viewport checks, and remaining risks. | Include screenshots or a local route when possible. |
|
|
76
|
+
| Tailwind design system | "Refactor these Tailwind components into semantic tokens and variants: theme extension, dark mode, class composition, dynamic class safety, and Storybook state coverage." | `fec-tailwind-design-system`, `fec-ui-design` | Token/variant plan or implementation with class governance and dark-mode checks. | Useful before a shared UI package grows too large. |
|
|
77
|
+
| Product-specific direction | "Create a product-specific design direction for a healthcare analytics dashboard: primary user tasks, visual anchor, information density, chart language, color roles, typography mood, and anti-patterns to avoid." | `fec-ui-design`, `fec-performance-optimizer` | Design direction, dashboard structure, chart UX guidance, and QA focus. | Include audience, data types, and whether data is real-time. |
|
|
78
|
+
| Design system generation | "Generate a design system direction for a premium booking app. Define semantic color roles, type scale, spacing/radius rules, component tone, motion principles, and what should be intentionally avoided." | `fec-ui-design`, `fec-design-token-mapper` | Product-aware design system proposal and token guidance. | Mention product category, brand tone, and target stack. |
|
|
79
|
+
| Master/Page overrides | "Before polishing checkout, read `design-system/Acme/MASTER.md` and check for `design-system/Acme/pages/checkout.md`. Apply page overrides only where they differ from the master system." | `fec-ui-design` | Page-level polish aligned to persistent design-system rules. | Use when a project keeps design decisions in repo docs. |
|
|
80
|
+
| Landing page direction | "Design a landing page direction for a B2B developer tool: first-screen hierarchy, proof points, product evidence, CTA placement, responsive sections, and a distinctive visual anchor that is not a generic gradient hero." | `fec-ui-design` | Landing structure, visual hierarchy, conversion flow, and anti-generic guidance. | Include offer, audience, and conversion goal. |
|
|
81
|
+
| Analytics dashboard UX | "Improve this operations dashboard for scanning under pressure: table/chart balance, real-time status, alert priority, drill-down paths, empty/error states, and responsive density." | `fec-ui-design`, `fec-accessibility-check` | Dashboard UX recommendations or UI changes with state coverage. | Include screenshots, sample data, or the local route. |
|
|
82
|
+
| Mobile commerce UI | "Design a mobile e-commerce product browsing flow with touch-safe controls, bottom navigation, filter/sort ergonomics, product media, loading/empty states, and checkout entry points." | `fec-ui-design`, `fec-accessibility-check` | Mobile UI direction, interaction states, and responsive constraints. | State whether this is mobile web or native-like web UI. |
|
|
83
|
+
| Fintech interface polish | "Polish this banking interface so it feels trustworthy and calm: balance visibility, transaction hierarchy, risk states, contrast, focus behavior, and restrained motion." | `fec-ui-design`, `fec-security-review` | Fintech-appropriate UI polish and risk-state guidance. | Include compliance or masking requirements if any. |
|
|
84
|
+
| Portfolio visual identity | "Create a distinctive portfolio direction for a designer/developer: project storytelling, navigation rhythm, case-study layout, media treatment, typography personality, and reduced-motion fallback." | `fec-ui-design`, `fec-svg-animation` | Portfolio UI direction and interaction guidance. | Provide personal brand tone and example projects. |
|
|
85
|
+
| Interaction motion | "Plan the motion system for this product page: Framer Motion vs GSAP choices, page transitions, scroll animation, reduced-motion fallback, lazy loading, and performance budgets." | `fec-motion-interaction`, `fec-ui-design` | Motion direction, tool choices, accessibility fallback, and verification checklist. | Include brand tone, device constraints, and whether motion is decorative or functional. |
|
|
86
|
+
| Anti-generic UI review | "Review this page for generic AI-app patterns: overused purple gradients, stacked cards, vague hero copy, weak product evidence, one-note color, and missing interaction states." | `fec-ui-design` | Anti-pattern findings and concrete replacement direction. | Works well with a screenshot or local URL. |
|
|
87
|
+
| Pre-delivery UI QA | "Run a pre-delivery UI QA pass across 375px, 768px, and 1440px: text overflow, focus rings, hover/active/disabled states, reduced motion, loading/empty/error states, and visual consistency." | `fec-ui-design`, `fec-accessibility-check` | UI QA checklist, findings, and fix recommendations. | Best near the end of implementation. |
|
|
88
|
+
| Design token mapping | "Map Figma variables for color, type, spacing, radius, and shadow into this repo's design token structure without breaking existing components." | `fec-design-token-mapper` | Token mapping proposal or code changes. | Include token naming rules. |
|
|
89
|
+
| Storybook docs | "Set up Storybook docs for `packages/ui/Button` and `Dialog`: MDX, states, accessibility addon, interaction tests, and visual baselines." | `fec-storybook-component-doc` | Storybook stories/docs and test guidance. | Include current Storybook status. |
|
|
90
|
+
|
|
91
|
+
## Testing
|
|
92
|
+
|
|
93
|
+
| Scenario | Prompt | Best for | Expected output | Notes |
|
|
94
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------- | --------------------------------------------------- |
|
|
95
|
+
| TDD implementation | "Use TDD to add coupon validation to checkout: write failing tests first, implement the minimum code, refactor, and keep the test list visible." | `/fec-tdd`, `fec-tdd-workflow` | Red-green-refactor loop with tests and code. | Best for contained behavior changes. |
|
|
96
|
+
| Component tests | "Write React Testing Library tests for `UserCard`: rendering, loading/error states, user-event interactions, accessibility assertions, and regression cases." | `fec-component-testing` | Component tests following local conventions. | Vue projects should ask for Vue Test Utils instead. |
|
|
97
|
+
| E2E smoke test | "Add Playwright smoke tests for login and checkout. Use Page Objects, stable selectors, CI-friendly retries, and trace artifacts on failure." | `fec-e2e-testing`, `fec-e2e-runner` | E2E tests, runner guidance, and summary report. | Include test account or mock strategy. |
|
|
98
|
+
| Flaky E2E diagnosis | "The checkout E2E test is flaky in CI. Analyze likely timing, network, storage, and selector issues, then stabilize it without hiding failures." | `fec-e2e-testing`, `fec-e2e-runner` | Root-cause analysis and targeted fix. | Include CI logs or traces. |
|
|
99
|
+
|
|
100
|
+
## Maintenance
|
|
101
|
+
|
|
102
|
+
| Scenario | Prompt | Best for | Expected output | Notes |
|
|
103
|
+
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------- |
|
|
104
|
+
| Build failure repair | "`pnpm lint`, `pnpm typecheck`, and `pnpm test` are failing. Fix them incrementally without weakening rules or skipping tests." | `/fec-build-fix`, `fec-validation-fix`, `fec-build-fixer` | Minimal fixes and validation report. | Paste exact failing commands. |
|
|
105
|
+
| Dead-code cleanup | "Find and safely remove unused exports, dead routes, stale styles, and unused dependencies. Preserve public API and write a report." | `/fec-refactor-clean`, `fec-refactor-clean`, `fec-refactor-cleaner` | Cleanup plan/changes and report. | Good before releases. |
|
|
106
|
+
| Documentation sync | "Update public docs so README, runtime docs, capability tables, and metadata match the current commands, skills, agents, hooks, and package files." | `/fec-doc-sync`, `fec-doc-sync`, `fec-doc-updater` | Synchronized docs and verification notes. | Avoid copying temporary reports into docs. |
|
|
107
|
+
| Source-backed upgrade | "Plan a safe upgrade for React Router/TanStack Query/Vite. Check official migration notes, compare current project usage, list breaking changes, and propose verification steps." | `fec-dependency-upgrade`, `fec-source-driven-development`, `fec-doc-sync` | Upgrade decision notes, affected files, migration risks, and validation checklist. | Pair with docs sync if public guidance changes. |
|
|
108
|
+
| Legacy maintenance | "Improve `public/js/legacy/cart.js` while keeping the current jQuery/MPA stack. Reduce risk, improve structure, and do not rewrite it to React yet." | `fec-legacy-web-standard` | Safe legacy maintenance changes or recommendations. | Mention browser support constraints. |
|
|
109
|
+
|
|
110
|
+
## Power-User Prompts
|
|
111
|
+
|
|
112
|
+
Use these when you know the internal entry point you want.
|
|
113
|
+
|
|
114
|
+
| Scenario | Prompt | Best for | Expected output | Notes |
|
|
115
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------------------------------------- | ----------------------------------------------------- |
|
|
116
|
+
| Slash command review | "`/fec-review` Review the last commit and write `reports/code-review-*.md` with severity, evidence, and merge recommendation." | `/fec-review` | Structured code-review report. | Claude-style runtimes expose slash commands directly. |
|
|
117
|
+
| Slash command plan | "`/fec-plan` Plan the dashboard analytics feature before implementation. Include component boundaries, data flow, state ownership, rollout steps, and implementation risks." | `/fec-plan` | Architecture proposal. | Use before complex work. |
|
|
118
|
+
| Slash command scaffold | "`/fec-scaffold page UserDetail` Create the standard page structure for a user detail view following this repo's conventions." | `/fec-scaffold` | Page/feature/component scaffold. | Confirm overwrite behavior if files exist. |
|
|
119
|
+
| Slash command test plan | "`/fec-plan` Build a risk-based test plan for the billing refactor." | `/fec-plan` | Test matrix and priority order. | Can be report-only. |
|
|
120
|
+
| Slash command TDD | "`/fec-tdd` Add password strength validation with failing tests first, then implementation." | `/fec-tdd` | TDD loop and validated change. | Keep scope small. |
|
|
121
|
+
| Slash command build fix | "`/fec-build-fix` Fix the failing validation commands from this log: <paste log>." | `/fec-build-fix` | Incremental validation fixes. | Paste exact logs. |
|
|
122
|
+
| Slash command cleanup | "`/fec-refactor-clean` Safely remove unused exports and dependencies from this package." | `/fec-refactor-clean` | Cleanup report and safe edits. | Run tests after. |
|
|
123
|
+
| Slash command docs | "`/fec-doc-sync` Sync README, runtime docs, and metadata with the current package contents." | `/fec-doc-sync` | Docs updates and verification. | Use before releases. |
|
|
124
|
+
| Explicit agent | "Delegate to `fec-code-reviewer` for a PR-style review of `src/features/payments/`, then summarize blockers first." | agent dispatch | Specialized agent report and summary. | Best for focused expert review. |
|