[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6QQ6HEHKF7DRHTGE70J93WF":3,"skill-same:01M6QQ6HEHKF7DRHTGE70J93WF":58},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":32,"linkOnly":33,"markdownContent":34,"markdownBody":35,"frontMatter":36,"refName":37,"commitSha":38,"skillDirectory":39,"forksCount":14,"repositoryHtmlUrl":40,"repositoryHomepageUrl":6,"ownerHtmlUrl":41,"ownerBlogUrl":6,"ownerDescription":42,"updatedAt":43,"install":44,"resources":57},"01M6QQ6HEHKF7DRHTGE70J93WF","dry-refactoring",null,"Guided workflow to eliminate copy-paste duplication detected by jscpd. Refactor clones using extract function, module, constant, or base class strategies.","lfr-ai\u002Fcopier-fullstack-template","lfr-ai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F233346551?v=4","01M6QPWTJWTSJV1TQTTY8ZPBYJ","Laurits Fromberg","01M6QPWTQ47BZGA4TH17H14N80",0,"MIT","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fdry-refactoring\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31],"refactoring","dry","dry refactoring","workflow","refactor","extract","base","duplication","strategies","module","copy","paste","jscpd","2026-11-10 10:12:30",false,"---\nname: dry-refactoring\ndescription: Guided workflow to eliminate copy-paste duplication detected by jscpd. Refactor clones using extract function, module, constant, or base class strategies.\n---\n\n# dry-refactoring\n\nGuided workflow to eliminate copy-paste duplication in source code. Use after running [jscpd](..\u002Fjscpd\u002FSKILL.md) to detect clones.\n\n## Prerequisites\n\nFirst, run jscpd to identify duplications:\n\n```bash\nnpx jscpd@4.0.5 --reporters ai \u003Cpath>\n```\n\nSee the **[jscpd](..\u002Fjscpd\u002FSKILL.md)** skill for full option reference.\n\n## Workflow\n\n1. Run jscpd with `--reporters ai` on the target path\n2. Parse each clone line to identify the two duplicated locations (file + line range)\n3. Read both code fragments from the source files\n4. Understand what the duplicated code does\n5. Design a refactoring: extract a shared function, class, module, or constant\n6. Apply the refactoring — update both locations and all other usages\n7. Re-run jscpd to confirm the clone is eliminated\n8. Repeat for remaining clones, highest-impact first\n\n## Refactoring Strategies\n\n| Strategy | When |\n|----------|------|\n| Extract function | Same logic repeated with different inputs |\n| Extract constant | Same literal values repeated |\n| Extract base class | Parallel class hierarchies with shared behaviour |\n| Extract module | Shared utilities across multiple modules |\n| Template method | Same algorithm structure, different steps |\n","# dry-refactoring\n\nGuided workflow to eliminate copy-paste duplication in source code. Use after running [jscpd](..\u002Fjscpd\u002FSKILL.md) to detect clones.\n\n## Prerequisites\n\nFirst, run jscpd to identify duplications:\n\n```bash\nnpx jscpd@4.0.5 --reporters ai \u003Cpath>\n```\n\nSee the **[jscpd](..\u002Fjscpd\u002FSKILL.md)** skill for full option reference.\n\n## Workflow\n\n1. Run jscpd with `--reporters ai` on the target path\n2. Parse each clone line to identify the two duplicated locations (file + line range)\n3. Read both code fragments from the source files\n4. Understand what the duplicated code does\n5. Design a refactoring: extract a shared function, class, module, or constant\n6. Apply the refactoring — update both locations and all other usages\n7. Re-run jscpd to confirm the clone is eliminated\n8. Repeat for remaining clones, highest-impact first\n\n## Refactoring Strategies\n\n| Strategy | When |\n|----------|------|\n| Extract function | Same logic repeated with different inputs |\n| Extract constant | Same literal values repeated |\n| Extract base class | Parallel class hierarchies with shared behaviour |\n| Extract module | Shared utilities across multiple modules |\n| Template method | Same algorithm structure, different steps |\n",{"name":5,"description":7},"main","f726ce2f2bb4e3bcc2f56c066598f4acd910c5ee",".github\u002Fskills\u002Fdry-refactoring","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template","https:\u002F\u002Fgithub.com\u002Flfr-ai","Optimizing for elegance","2026-07-20 12:19:48",{"source":8,"skillName":5,"commands":45,"prompt":55,"zipAvailable":56},[46,49,52],{"tool":47,"command":48},"npx","npx skills add lfr-ai\u002Fcopier-fullstack-template --skill dry-refactoring",{"tool":50,"command":51},"bunx","bunx skills add lfr-ai\u002Fcopier-fullstack-template --skill dry-refactoring",{"tool":53,"command":54},"pnpm","pnpm dlx skills add lfr-ai\u002Fcopier-fullstack-template --skill dry-refactoring","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fdry-refactoring\u002FSKILL.md",true,[],[59,92,104,110,127,133],{"skillNo":60,"name":61,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":75,"publishedAt":32},"01M6QQGVYW8BZ3W165A5YMJ1PF","ui-ux-frontend","Frontend UX, accessibility, responsive layout, and Storybook interaction quality standards.","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Fui-ux-frontend\u002FSKILL.md",[65,70],{"categoryNo":66,"categoryName":67,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":71,"categoryName":72,"taxonomyType":73,"taxonomyTypeDesc":74},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91],"ui ux","ui ux frontend","ui","ux","frontend","storybook","frontend ux","interaction","layout","responsive","mdx","tsx","standards","quality","accessibility","css",{"skillNo":93,"name":94,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":100,"publishedAt":32},"01M6QQGS7N3ENQZR2Y5JBRYDHD","testing-conventions","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Ftesting-conventions\u002FSKILL.md",[97],{"categoryNo":98,"categoryName":99,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000008","测试与质量",[101,102,103],"conventions","testing conventions","testing",{"skillNo":105,"name":106,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":107,"categories":108,"keywords":109,"publishedAt":32},"01M6QQGQKA9Q6A147WXMS7QPGX","tdd","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Ftdd\u002FSKILL.md",[],[106],{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":117,"publishedAt":32},"01M6QQG5AZPRWSR6SSCCDDPAM3","shadcn-ui","shadcn\u002Fui component conventions and composition patterns","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Fshadcn-ui\u002FSKILL.md",[116],{"categoryNo":71,"categoryName":72,"taxonomyType":73,"taxonomyTypeDesc":74},[118,78,119,120,87,121,122,123,124,101,125,126],"shadcn ui","shadcn","component","Composition","src","composition patterns","presentation","patterns","ui component",{"skillNo":128,"name":129,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":132,"publishedAt":32},"01M6QQG3WMMB8X8C4T8PR7WBV4","sdd","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Fsdd\u002FSKILL.md",[],[129],{"skillNo":134,"name":135,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":138,"publishedAt":32},"01M6QQG241NAC5PQFXFD01NR16","quality-gate","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Fquality-gate\u002FSKILL.md",[],[139,89,140],"quality gate","gate"]