[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C5JC89CBTCEFSXMTNFFECT":3,"skill-same:01M6C5JC89CBTCEFSXMTNFFECT":114},{"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":47,"linkOnly":48,"markdownContent":49,"markdownBody":50,"frontMatter":51,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":6,"ownerHtmlUrl":65,"ownerBlogUrl":6,"ownerDescription":66,"updatedAt":67,"install":68,"resources":81},"01M6C5JC89CBTCEFSXMTNFFECT","dry-consolidation",null,"Find and extract duplicated code into shared abstractions. Use when seeing repeated utilities, copy-pasted components, duplicated hooks, or boilerplate repeated across files.","laurigates\u002Fclaude-plugins","laurigates","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F13014001?v=4","01M6C59YHWS9C7KMXKSRX1YXNP","Lauri Gates","01M6C59YP2APG9YAM4DWYQYGFJ",59,"MIT","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fcode-quality-plugin\u002Fskills\u002Fdry-consolidation\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"consolidation","dry","dry consolidation","extract","2026","when","Utilities","scope","shared","across","files","bun","hooks","use","directory","edit","write","read","find","ast","grep","Bash","npm","yarn","code","run","components","test","2026-11-10 10:12:30",false,"---\nname: dry-consolidation\ndescription: Find and extract duplicated code into shared abstractions. Use when seeing repeated utilities, copy-pasted components, duplicated hooks, or boilerplate repeated across files.\nargs: \"[PATH] [--scope \u003Cutilities|components|hooks|all>] [--dry-run]\"\nallowed-tools: Read, Write, Edit, Grep, Glob, Bash(npx tsc *), Bash(npm run *), Bash(npm test *), Bash(npx *), Bash(bun *), Bash(pnpm *), Bash(yarn *), Bash(pytest *), Bash(ty *), Bash(ruff *), Bash(cargo *), Bash(ast-grep *), Bash(sg *), Task\nmodel: opus\nargument-hint: path or directory to scan for duplication\ncreated: 2026-02-06\nmodified: 2026-09-02\nreviewed: 2026-09-02\nagent: general-purpose\ncontext: fork\n---\n\n# DRY Consolidation\n\nSystematic extraction of duplicated code into shared, tested abstractions.\n\n## When to Use This Skill\n\n| Use this skill when... | Use these instead when... |\n|------------------------|--------------------------|\n| Multiple files have identical\u002Fnear-identical code blocks | Single file needs cleanup → `\u002Fcode:refactor` |\n| Copy-pasted utility functions across components | Looking for anti-patterns without fixing → `\u002Fcode:antipatterns` |\n| Repeated UI patterns (dialogs, pagination, error states) | Functional refactoring of a file or directory → `\u002Fcode:refactor` |\n| Duplicated hooks or state management boilerplate | Structural code search only → `ast-grep-search` |\n| Near-duplicate copy-paste with renamed vars needs enumerating (jscpd finds the clusters here) | Matching one known structural pattern → `ast-grep-search` |\n| Import blocks are bloated from repeated inline patterns | Linting\u002Fformatting issues → `\u002Fcode:lint` |\n\n## Context\n\n- Target path: !`echo \"$1\"`\n- Project type: !`find . -maxdepth 1 \\( -name \"package.json\" -o -name \"Cargo.toml\" -o -name \"pyproject.toml\" -o -name \"go.mod\" \\)`\n- Source directories: !`find . -maxdepth 1 -type d \\( -name \"src\" -o -name \"lib\" -o -name \"app\" -o -name \"components\" -o -name \"packages\" \\)`\n- Test framework: !`find . -maxdepth 2 \\( -name \"vitest.config.*\" -o -name \"jest.config.*\" -o -name \"pytest.ini\" -o -name \"conftest.py\" \\)`\n- Existing shared utilities: !`find . \\( -path \"*\u002Flib\u002F*\" -o -path \"*\u002Futils\u002F*\" -o -path \"*\u002Fshared\u002F*\" -o -path \"*\u002Fcommon\u002F*\" -o -path \"*\u002Fhooks\u002F*\" \\) -type f -print -quit`\n\n## Parameters\n\n- `$1`: Path or directory to scan (defaults to `src\u002F`)\n- `--scope`: Focus on a specific extraction type: `utilities`, `components`, `hooks`, or `all` (default: `all`)\n- `--dry-run`: Analyze and report duplications without making changes\n\n## Execution\n\nExecute this 7-step consolidation workflow. Track each extraction as a separate task with `TodoWrite` when the session has the task tools (see `.claude\u002Frules\u002Fagentic-permissions.md` § Task-tool availability), otherwise as a checklist in your response.\n\n### Step 1: Discover duplicate clusters (deterministic clone detection)\n\nEnumerate duplicate ranges with a deterministic clone detector, then read **only the reported ranges** — not whole candidate files. This keeps discovery reproducible and cheap. Token-based detection (jscpd) finds copy-paste independent of whitespace\u002Fformatting and of the enclosing symbol name — clone pairs a name-based Grep misses when the wrapping function is renamed. ast-grep (1b) then adds tolerance for variables renamed *inside* the block.\n\n#### 1a. Token-based near-duplicates with jscpd\n\n`jscpd` is a token-based copy\u002Fpaste detector that supports 150+ languages despite the \"js\" in the name; `npx` runs it with no global install. Run it over the target path:\n\n```bash\nnpx jscpd --reporters json --min-tokens 50 --output \u002Ftmp\u002Fjscpd-dry --silent \u003Cpath>\n```\n\nIt writes `\u002Ftmp\u002Fjscpd-dry\u002Fjscpd-report.json`. Read that report and parse its `duplicates` array — each entry gives the exact file\u002Fline ranges of a clone pair plus its size in tokens\u002Flines:\n\nAn example of the report shape is in [references\u002Fclone-report.md](references\u002Fclone-report.md).\n\nFor each reported clone, **Read only the line ranges** (`Read` with `offset`\u002F`limit` around `start`\u002F`end`) to confirm the duplication and classify it — do not Read whole candidate files. jscpd similarity is high by construction for a reported clone (a `--min-tokens` match); note the tokens\u002Flines for the Extraction Plan.\n\n#### 1b. Structural confirmation with ast-grep\n\nOnce jscpd surfaces a cluster, confirm it is the same *shape* — same call-shape \u002F same block modulo captured variables — with ast-grep metavariables. `$VAR` \u002F `$INIT` match any identifier\u002Fexpression, so a block differing only in renamed captures still matches:\n\n```bash\nast-grep -p 'const $VAR = useState($INIT)' --lang tsx \u003Cpath>\n```\n\nUse this to separate a genuine extractable duplicate from a coincidental token overlap before planning the extraction. (For a standalone structural search without extraction, use the `ast-grep-search` skill.)\n\n#### 1c. Graceful fallback (Grep) when the detector is unavailable\n\nWhen `npx`\u002F`jscpd` is unavailable, or the ecosystem has no `npx` on PATH, fall back to agent-driven text search:\n\n1. Use Grep to find repeated function names, variable patterns, and import clusters\n2. Use Glob to identify files with similar structure (e.g., all `*List.tsx`, all `*Detail.tsx`)\n3. Read candidate files to confirm duplication and measure scope\n\nThis fallback has lower recall for near-duplicates (renamed variables, reordered params) — prefer the jscpd path when available, and reserve Grep for when it is not.\n\nThe duplication signals both paths feed into Step 2 are listed in\n[references\u002Fduplication-signals.md](references\u002Fduplication-signals.md).\n\n### Step 2: Classify duplications\n\nGroup discovered duplications into extraction categories:\n\n| Category | Extract Into | Location Convention |\n|----------|-------------|---------------------|\n| **Utilities** | Pure functions | `src\u002Flib\u002Futils\u002F` or `src\u002Futils\u002F` |\n| **Components** | Shared UI components | `src\u002Fcomponents\u002Fui\u002F` or `src\u002Fcomponents\u002Fshared\u002F` |\n| **Hooks** | Custom React\u002FVue hooks | `src\u002Fhooks\u002F` or `src\u002Fcomposables\u002F` |\n| **Types** | Shared type definitions | `src\u002Ftypes\u002F` or alongside the abstraction |\n\nFollow the project's existing conventions for shared code location. If no convention exists, propose one based on the framework.\n\n### Step 3: Plan extractions\n\nFor each duplication cluster, plan the extraction:\n\n1. **Name the abstraction** — Use a clear, descriptive name that reflects the shared behavior\n2. **Define the interface** — Determine parameters needed to cover all usage variations\n3. **Choose the location** — Follow project conventions for shared code placement\n4. **List all consumers** — Identify every file that will be updated\n5. **Assess risk** — Note any subtle differences between duplicated instances that need parameterization\n\nPresent the plan to the user before proceeding (unless `--dry-run` was not specified and the scope is clear).\n\n**Plan format:**\n```\n## Extraction Plan\n\n### 1. [Abstraction Name] → [target file path]\n- Type: utility | component | hook\n- Replaces: [N] identical blocks across [M] files\n- Consumers: [list of files]\n- Parameters: [any variations that need to be parameterized]\n- Duplicated: [N] tokens \u002F [N] lines (from jscpd; blank when the Grep fallback was used)\n- Similarity: [N]% (from jscpd; \"exact\" when ast-grep-confirmed as the same shape)\n- Estimated lines saved: [N]\n```\n\nThe `Duplicated` and `Similarity` fields come from jscpd's report (tokens\u002Flines per clone, and the cluster's percentage) — a quantified `--dry-run` report instead of a best-effort narrative. When the Grep fallback (1c) supplied the cluster, leave them blank or note \"grep-estimated\".\n\n### Step 4: Extract shared abstractions\n\nExecute each planned extraction:\n\n1. **Create the shared abstraction** with proper typing and documentation\n2. **Replace each instance** in consumer files with an import + usage of the new abstraction\n3. **Handle variations** — parameterize differences between instances rather than creating multiple abstractions\n4. **Update imports** — add the new import, remove imports that were only needed for the inline version\n\n**Extraction order:** Start with utilities (no dependencies), then components, then hooks (may depend on utilities\u002Fcomponents).\n\nMark each extraction as completed in the tracker before moving to the next.\n\n### Step 5: Write tests\n\nWrite tests for each extracted abstraction:\n\nPick the test approach per abstraction type (utility, component, hook, types) from\n[references\u002Ftest-and-verify.md](references\u002Ftest-and-verify.md#test-approach-by-abstraction-type).\n\nPlace test files adjacent to the abstraction or in the project's test directory, following existing conventions.\n\n### Step 6: Clean up dead code\n\nAfter all extractions are complete:\n\n1. **Remove unused imports** from all updated consumer files\n2. **Remove dead code** — inline helper functions that are now replaced\n3. **Verify no orphaned references** — search for any remaining references to removed code\n\n### Step 7: Verify all checks pass\n\nRun the full verification suite:\n\nRun type checking, linting, and the full test suite with the project's tools — the\nTypeScript\u002FJavaScript, Python, and Rust command sets are in\n[references\u002Ftest-and-verify.md](references\u002Ftest-and-verify.md#verification-commands).\n\nAll three must pass. If any fail, fix the issues before reporting completion.\n\n### Output Summary\n\nAfter all phases complete, report using the summary template in\n[references\u002Foutput-summary.md](references\u002Foutput-summary.md).\n\n## Agentic Optimizations\n\nCompact command forms (clone scan, shape confirm, scoped runs, fast verify) are in\n[references\u002Fagentic-optimizations.md](references\u002Fagentic-optimizations.md).\n\n## See Also\n\nSibling skills (`\u002Fcode:refactor`, `\u002Fcode:antipatterns`, `ast-grep-search`) and follow-ups\n(`\u002Fcode:dead-code`, `\u002Fcode:complexity`) are listed in [references\u002Frelated.md](references\u002Frelated.md).\n","# DRY Consolidation\n\nSystematic extraction of duplicated code into shared, tested abstractions.\n\n## When to Use This Skill\n\n| Use this skill when... | Use these instead when... |\n|------------------------|--------------------------|\n| Multiple files have identical\u002Fnear-identical code blocks | Single file needs cleanup → `\u002Fcode:refactor` |\n| Copy-pasted utility functions across components | Looking for anti-patterns without fixing → `\u002Fcode:antipatterns` |\n| Repeated UI patterns (dialogs, pagination, error states) | Functional refactoring of a file or directory → `\u002Fcode:refactor` |\n| Duplicated hooks or state management boilerplate | Structural code search only → `ast-grep-search` |\n| Near-duplicate copy-paste with renamed vars needs enumerating (jscpd finds the clusters here) | Matching one known structural pattern → `ast-grep-search` |\n| Import blocks are bloated from repeated inline patterns | Linting\u002Fformatting issues → `\u002Fcode:lint` |\n\n## Context\n\n- Target path: !`echo \"$1\"`\n- Project type: !`find . -maxdepth 1 \\( -name \"package.json\" -o -name \"Cargo.toml\" -o -name \"pyproject.toml\" -o -name \"go.mod\" \\)`\n- Source directories: !`find . -maxdepth 1 -type d \\( -name \"src\" -o -name \"lib\" -o -name \"app\" -o -name \"components\" -o -name \"packages\" \\)`\n- Test framework: !`find . -maxdepth 2 \\( -name \"vitest.config.*\" -o -name \"jest.config.*\" -o -name \"pytest.ini\" -o -name \"conftest.py\" \\)`\n- Existing shared utilities: !`find . \\( -path \"*\u002Flib\u002F*\" -o -path \"*\u002Futils\u002F*\" -o -path \"*\u002Fshared\u002F*\" -o -path \"*\u002Fcommon\u002F*\" -o -path \"*\u002Fhooks\u002F*\" \\) -type f -print -quit`\n\n## Parameters\n\n- `$1`: Path or directory to scan (defaults to `src\u002F`)\n- `--scope`: Focus on a specific extraction type: `utilities`, `components`, `hooks`, or `all` (default: `all`)\n- `--dry-run`: Analyze and report duplications without making changes\n\n## Execution\n\nExecute this 7-step consolidation workflow. Track each extraction as a separate task with `TodoWrite` when the session has the task tools (see `.claude\u002Frules\u002Fagentic-permissions.md` § Task-tool availability), otherwise as a checklist in your response.\n\n### Step 1: Discover duplicate clusters (deterministic clone detection)\n\nEnumerate duplicate ranges with a deterministic clone detector, then read **only the reported ranges** — not whole candidate files. This keeps discovery reproducible and cheap. Token-based detection (jscpd) finds copy-paste independent of whitespace\u002Fformatting and of the enclosing symbol name — clone pairs a name-based Grep misses when the wrapping function is renamed. ast-grep (1b) then adds tolerance for variables renamed *inside* the block.\n\n#### 1a. Token-based near-duplicates with jscpd\n\n`jscpd` is a token-based copy\u002Fpaste detector that supports 150+ languages despite the \"js\" in the name; `npx` runs it with no global install. Run it over the target path:\n\n```bash\nnpx jscpd --reporters json --min-tokens 50 --output \u002Ftmp\u002Fjscpd-dry --silent \u003Cpath>\n```\n\nIt writes `\u002Ftmp\u002Fjscpd-dry\u002Fjscpd-report.json`. Read that report and parse its `duplicates` array — each entry gives the exact file\u002Fline ranges of a clone pair plus its size in tokens\u002Flines:\n\nAn example of the report shape is in [references\u002Fclone-report.md](references\u002Fclone-report.md).\n\nFor each reported clone, **Read only the line ranges** (`Read` with `offset`\u002F`limit` around `start`\u002F`end`) to confirm the duplication and classify it — do not Read whole candidate files. jscpd similarity is high by construction for a reported clone (a `--min-tokens` match); note the tokens\u002Flines for the Extraction Plan.\n\n#### 1b. Structural confirmation with ast-grep\n\nOnce jscpd surfaces a cluster, confirm it is the same *shape* — same call-shape \u002F same block modulo captured variables — with ast-grep metavariables. `$VAR` \u002F `$INIT` match any identifier\u002Fexpression, so a block differing only in renamed captures still matches:\n\n```bash\nast-grep -p 'const $VAR = useState($INIT)' --lang tsx \u003Cpath>\n```\n\nUse this to separate a genuine extractable duplicate from a coincidental token overlap before planning the extraction. (For a standalone structural search without extraction, use the `ast-grep-search` skill.)\n\n#### 1c. Graceful fallback (Grep) when the detector is unavailable\n\nWhen `npx`\u002F`jscpd` is unavailable, or the ecosystem has no `npx` on PATH, fall back to agent-driven text search:\n\n1. Use Grep to find repeated function names, variable patterns, and import clusters\n2. Use Glob to identify files with similar structure (e.g., all `*List.tsx`, all `*Detail.tsx`)\n3. Read candidate files to confirm duplication and measure scope\n\nThis fallback has lower recall for near-duplicates (renamed variables, reordered params) — prefer the jscpd path when available, and reserve Grep for when it is not.\n\nThe duplication signals both paths feed into Step 2 are listed in\n[references\u002Fduplication-signals.md](references\u002Fduplication-signals.md).\n\n### Step 2: Classify duplications\n\nGroup discovered duplications into extraction categories:\n\n| Category | Extract Into | Location Convention |\n|----------|-------------|---------------------|\n| **Utilities** | Pure functions | `src\u002Flib\u002Futils\u002F` or `src\u002Futils\u002F` |\n| **Components** | Shared UI components | `src\u002Fcomponents\u002Fui\u002F` or `src\u002Fcomponents\u002Fshared\u002F` |\n| **Hooks** | Custom React\u002FVue hooks | `src\u002Fhooks\u002F` or `src\u002Fcomposables\u002F` |\n| **Types** | Shared type definitions | `src\u002Ftypes\u002F` or alongside the abstraction |\n\nFollow the project's existing conventions for shared code location. If no convention exists, propose one based on the framework.\n\n### Step 3: Plan extractions\n\nFor each duplication cluster, plan the extraction:\n\n1. **Name the abstraction** — Use a clear, descriptive name that reflects the shared behavior\n2. **Define the interface** — Determine parameters needed to cover all usage variations\n3. **Choose the location** — Follow project conventions for shared code placement\n4. **List all consumers** — Identify every file that will be updated\n5. **Assess risk** — Note any subtle differences between duplicated instances that need parameterization\n\nPresent the plan to the user before proceeding (unless `--dry-run` was not specified and the scope is clear).\n\n**Plan format:**\n```\n## Extraction Plan\n\n### 1. [Abstraction Name] → [target file path]\n- Type: utility | component | hook\n- Replaces: [N] identical blocks across [M] files\n- Consumers: [list of files]\n- Parameters: [any variations that need to be parameterized]\n- Duplicated: [N] tokens \u002F [N] lines (from jscpd; blank when the Grep fallback was used)\n- Similarity: [N]% (from jscpd; \"exact\" when ast-grep-confirmed as the same shape)\n- Estimated lines saved: [N]\n```\n\nThe `Duplicated` and `Similarity` fields come from jscpd's report (tokens\u002Flines per clone, and the cluster's percentage) — a quantified `--dry-run` report instead of a best-effort narrative. When the Grep fallback (1c) supplied the cluster, leave them blank or note \"grep-estimated\".\n\n### Step 4: Extract shared abstractions\n\nExecute each planned extraction:\n\n1. **Create the shared abstraction** with proper typing and documentation\n2. **Replace each instance** in consumer files with an import + usage of the new abstraction\n3. **Handle variations** — parameterize differences between instances rather than creating multiple abstractions\n4. **Update imports** — add the new import, remove imports that were only needed for the inline version\n\n**Extraction order:** Start with utilities (no dependencies), then components, then hooks (may depend on utilities\u002Fcomponents).\n\nMark each extraction as completed in the tracker before moving to the next.\n\n### Step 5: Write tests\n\nWrite tests for each extracted abstraction:\n\nPick the test approach per abstraction type (utility, component, hook, types) from\n[references\u002Ftest-and-verify.md](references\u002Ftest-and-verify.md#test-approach-by-abstraction-type).\n\nPlace test files adjacent to the abstraction or in the project's test directory, following existing conventions.\n\n### Step 6: Clean up dead code\n\nAfter all extractions are complete:\n\n1. **Remove unused imports** from all updated consumer files\n2. **Remove dead code** — inline helper functions that are now replaced\n3. **Verify no orphaned references** — search for any remaining references to removed code\n\n### Step 7: Verify all checks pass\n\nRun the full verification suite:\n\nRun type checking, linting, and the full test suite with the project's tools — the\nTypeScript\u002FJavaScript, Python, and Rust command sets are in\n[references\u002Ftest-and-verify.md](references\u002Ftest-and-verify.md#verification-commands).\n\nAll three must pass. If any fail, fix the issues before reporting completion.\n\n### Output Summary\n\nAfter all phases complete, report using the summary template in\n[references\u002Foutput-summary.md](references\u002Foutput-summary.md).\n\n## Agentic Optimizations\n\nCompact command forms (clone scan, shape confirm, scoped runs, fast verify) are in\n[references\u002Fagentic-optimizations.md](references\u002Fagentic-optimizations.md).\n\n## See Also\n\nSibling skills (`\u002Fcode:refactor`, `\u002Fcode:antipatterns`, `ast-grep-search`) and follow-ups\n(`\u002Fcode:dead-code`, `\u002Fcode:complexity`) are listed in [references\u002Frelated.md](references\u002Frelated.md).\n",{"args":52,"name":5,"agent":53,"model":54,"context":55,"created":56,"modified":57,"reviewed":57,"description":7,"allowed-tools":58,"argument-hint":59},"[PATH] [--scope \u003Cutilities|components|hooks|all>] [--dry-run]","general-purpose","opus","fork",1770336000000,1788307200000,"Read, Write, Edit, Grep, Glob, Bash(npx tsc *), Bash(npm run *), Bash(npm test *), Bash(npx *), Bash(bun *), Bash(pnpm *), Bash(yarn *), Bash(pytest *), Bash(ty *), Bash(ruff *), Bash(cargo *), Bash(ast-grep *), Bash(sg *), Task","path or directory to scan for duplication","main","bdd0582f1a2ba53d21061835bfd72d45f2f954f4","code-quality-plugin\u002Fskills\u002Fdry-consolidation",6,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins","https:\u002F\u002Fgithub.com\u002Flaurigates","Linux enthusiast, cloud engineer, neovim addict, electronics hobbyist.","2026-11-11 01:25:01",{"source":8,"skillName":5,"commands":69,"prompt":79,"zipAvailable":80},[70,73,76],{"tool":71,"command":72},"npx","npx skills add laurigates\u002Fclaude-plugins --skill dry-consolidation",{"tool":74,"command":75},"bunx","bunx skills add laurigates\u002Fclaude-plugins --skill dry-consolidation",{"tool":77,"command":78},"pnpm","pnpm dlx skills add laurigates\u002Fclaude-plugins --skill dry-consolidation","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fcode-quality-plugin\u002Fskills\u002Fdry-consolidation\u002FSKILL.md",true,[82,88,92,96,100,104,108],{"path":83,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":86,"sourceHtmlUrl":87},"references\u002Fagentic-optimizations.md","REFERENCE","参考文档",792,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fcode-quality-plugin\u002Fskills\u002Fdry-consolidation\u002Freferences\u002Fagentic-optimizations.md",{"path":89,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":90,"sourceHtmlUrl":91},"references\u002Fclone-report.md",422,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fcode-quality-plugin\u002Fskills\u002Fdry-consolidation\u002Freferences\u002Fclone-report.md",{"path":93,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":94,"sourceHtmlUrl":95},"references\u002Fduplication-signals.md",574,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fcode-quality-plugin\u002Fskills\u002Fdry-consolidation\u002Freferences\u002Fduplication-signals.md",{"path":97,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":98,"sourceHtmlUrl":99},"references\u002Foutput-summary.md",486,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fcode-quality-plugin\u002Fskills\u002Fdry-consolidation\u002Freferences\u002Foutput-summary.md",{"path":101,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":102,"sourceHtmlUrl":103},"references\u002Frelated.md",455,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fcode-quality-plugin\u002Fskills\u002Fdry-consolidation\u002Freferences\u002Frelated.md",{"path":105,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":106,"sourceHtmlUrl":107},"references\u002Ftest-and-verify.md",985,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fcode-quality-plugin\u002Fskills\u002Fdry-consolidation\u002Freferences\u002Ftest-and-verify.md",{"path":109,"resourceType":110,"resourceTypeDesc":111,"sizeBytes":112,"sourceHtmlUrl":113},"scripts\u002Ftests\u002Ftest-dry-consolidation.sh","SCRIPT","脚本",2459,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fcode-quality-plugin\u002Fskills\u002Fdry-consolidation\u002Fscripts\u002Ftests\u002Ftest-dry-consolidation.sh",[115,142,161,177,199,228],{"skillNo":116,"name":117,"nameZh":6,"description":118,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":126,"publishedAt":47},"01M70PFHMH9ADY0CRE6047Y4B2","kitty-show-image","Show the user an image with a note on what to judge, via a file send or a labelled kitty tab. Use when the user must see an image, or icat fails with no \u002Fdev\u002Ftty.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fkitty-plugin\u002Fskills\u002Fkitty-show-image\u002FSKILL.md",[121],{"categoryNo":122,"categoryName":123,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[127,128,129,130,131,132,133,134,135,136,32,24,40,137,138,139,140,141,23,36],"show","kitty show image","image","kitty","show image","ls","get","send","open","dev","file","text","with","xdg","via",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":148,"publishedAt":47},"01M70PFEN18HKQ4RCQ1VPGMPTB","kitty-session-persistence","Snapshot and restore kitty terminal sessions on macOS. Use when surviving WindowServer hangs without losing tabs, configuring snapshots, or restoring after a force-reboot.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fkitty-plugin\u002Fskills\u002Fkitty-session-persistence\u002FSKILL.md",[],[130,149,150,151,152,153,24,40,154,155,156,23,36,35,34,157,158,159,160,32],"kitty session persistence","session","persistence","false","snapshots","uname","reboot","terminal","snapshot","macos","sessions","restore",{"skillNo":162,"name":163,"nameZh":6,"description":164,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":165,"categories":166,"keywords":167,"publishedAt":47},"01M70PFC77XGXCVQ1543VGZHYR","kitty-remote-control","Safe kitty remote control from an agent — read panes with kitty @ ls\u002Fget-text, notify, and never mutate the live terminal unasked. Use when running inside kitty.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fkitty-plugin\u002Fskills\u002Fkitty-remote-control\u002FSKILL.md",[],[168,169,130,170,171,132,172,173,133,174,175,32,24,176,40,138,139,156,23,36],"kitty remote control","remote","control","remote control","running","never","panes","notify","query",{"skillNo":178,"name":179,"nameZh":6,"description":180,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":181,"categories":182,"keywords":183,"publishedAt":47},"01M70P6WVMCT5JG4SACTM69AF9","docs-reference-check","Dangling doc-reference gate: flag markdown naming repo paths or relative links that no longer exist. Use when docs cite moved\u002Fdeleted files, or wiring a doc-drift lint.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fdocumentation-plugin\u002Fskills\u002Fdocs-reference-check\u002FSKILL.md",[],[184,185,186,187,188,189,190,191,29,192,32,24,40,193,137,194,195,196,197,198],"docs reference check","check","reference check","reference","docs","links","python3","repo","auto","drift","lint","wiring","chezmoi","references","cp",{"skillNo":200,"name":201,"nameZh":6,"description":202,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":203,"categories":204,"keywords":214,"publishedAt":47},"01M6C6NDE7DAQGNWSF22J5CJ0Z","youtube-upload","Upload a video to YouTube via the Data API v3 and edit its title, description, tags or thumbnail afterwards. Use when publishing or retitling a YouTube video.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fyoutube-plugin\u002Fskills\u002Fyoutube-upload\u002FSKILL.md",[205,208,209],{"categoryNo":206,"categoryName":207,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":122,"categoryName":123,"taxonomyType":124,"taxonomyTypeDesc":125},{"categoryNo":210,"categoryName":211,"taxonomyType":212,"taxonomyTypeDesc":213},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[215,216,217,218,190,44,36,219,34,220,221,222,32,40,137,223,224,24,225,226,227,141,23],"youtube upload","upload","youtube","Video","uv run","publishing","data","uv","api","v3","tags","id","title",{"skillNo":229,"name":230,"nameZh":6,"description":231,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":232,"categories":233,"keywords":237,"publishedAt":47},"01M6C6NABWW1X58KJJM4F6GQMQ","youtube-studio-share","Share a private YouTube video with a whole Google Workspace organization by scripting YouTube Studio in the browser. Use when a video must be org-only.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fyoutube-plugin\u002Fskills\u002Fyoutube-studio-share\u002FSKILL.md",[234],{"categoryNo":235,"categoryName":236,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000023","Skill与智能体开发",[238,239,240,241,217,218,242,243,244,245,246,36,247,248,249,250,32,251,24,139,252,23],"youtube studio share","share","youtube studio","studio","browser","javascript","scripting","google workspace","workspace","tool","google","only","MCP","chrome","organization"]