Skip to content
Back to skills

dry-eyes

CSecurity

Finds SEMANTIC duplicate code across a whole repository — the same business rule, calculation, or UI/UX pattern implemented independently more than once, often with DIFFERENT behavior each time (e.g. one screen shows an error toast, another doesn't, a third shows both a toast and an inline error). Two subcommands — `/dry-eyes init` (profile the repo, pick which cheap deterministic duplication signals fit it, design tailored categories for a supplementary LLM sweep — auto-runs non-interactivel...

  • 1 star
  • 1 vote
  • 0 copies
  • 11 views
  • Added October 16, 2026
developmenttypescriptgorefactoringgitfrontendbackendsecurity

Security analysis

C70/100
  • highContains path traversal sequences that could access files outside intended directoriesin assets/collect-signals.sh
  • highPerforms destructive filesystem operationsin assets/collect-signals.sh

Pro scans all 9 files and shows the line behind each finding

Scanned October 16, 2026

npx -y skills add kigiela/dry-eyes --skill dry-eyes --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of dry-eyes?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for dry-eyes
[![Security: C — Skills Directory](https://www.skillsdirectory.com/api/skills/kigiela-dry-eyes/badge)](https://www.skillsdirectory.com/skills/kigiela-dry-eyes)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dry-eyes
description: >-
  Finds SEMANTIC duplicate code across a whole repository — the same
  business rule, calculation, or UI/UX pattern implemented independently
  more than once, often with DIFFERENT behavior each time (e.g. one screen
  shows an error toast, another doesn't, a third shows both a toast and an
  inline error). Two subcommands — `/dry-eyes init` (profile the repo, pick
  which cheap deterministic duplication signals fit it, design tailored
  categories for a supplementary LLM sweep — auto-runs non-interactively if
  skipped) and `/dry-eyes scan` (gather the signals, cluster the candidates,
  verify each cluster skeptically, then compare every variant against the
  others AND against what a correct implementation would need). Crucially,
  a cluster's verdict is never just "which one wins": it can and often does
  conclude that NONE of the existing variants is fully correct, and
  describes what a correct implementation would have to handle that none
  of them do. NOT a copy-paste/token clone detector — jscpd, PMD-CPD and
  similar tools already find literal clones cheaply and deterministically;
  this is for the duplication those tools cannot see, where two
  independently-written implementations mean the same thing but share no
  text at all. Read-only, full-repo only — never edits code, no diff/PR
  mode. Trigger on: find duplicate code, find duplicated business logic,
  duplicated validation or calculation, same rule implemented twice,
  inconsistent error handling or toasts across screens, DRY violations,
  code-duplication report, refactoring backlog for duplicated logic,
  "dry-eyes init/scan"; "código duplicado", "regra de negócio duplicada",
  "mesma validação implementada em dois lugares", "cálculo duplicado em
  vários lugares", "mensagens de erro inconsistentes entre telas", "toast em
  algumas telas e não em outras", "violação de DRY", "relatório de
  duplicação de código"; "código duplicado", "regla de negocio duplicada",
  "misma validación implementada en dos lugares", "cálculo duplicado en
  varios lugares", "mensajes de error inconsistentes entre pantallas",
  "violación de DRY", "informe de duplicación de código".
---

# DRY Eyes — semantic duplicate-code scans

Two implementations rarely look identical when someone reimplements the
same rule independently — different names, different shape, sometimes a
different language of variable names. This tool doesn't stop at "these two
things look similar": every candidate is read and compared for real, and
the comparison's job is to say what a *correct* implementation of the
concept actually requires — then check each variant against that bar. It's
common, not rare, for the answer to be "none of them." When duplicates
exist, the interesting finding usually isn't which one is right — it's that
neither is, and there's a third or fourth approach, not yet written
anywhere, that would be.

## Why this is not jscpd / PMD-CPD (and doesn't replace them)

Textual clone detectors compare tokens: they're fast, deterministic, and
very good at catching literal copy-paste. That's a solved problem this tool
doesn't reinvent — `/dry-eyes scan` runs its own cheap deterministic
signals first (repeated string literals, mirrored file paths, shared
normalized lines, domain-gated name families, inconsistent UI/UX
mechanisms for the same concern) for exactly the same reason those tools
exist: most duplication candidates can be found without spending an LLM
call. What a token-matching tool cannot do is judge *meaning* — two
functions with nothing textually in common that both compute the same
discount, or a screen that shows a toast next to three screens that don't,
are invisible to it. That's what the LLM layer here is for: verifying a
candidate is a genuine reimplementation (not already shared, not
coincidental), then comparing every variant's actual behavior against what
the concept requires. The two approaches are complementary, not
competing — see `config.signals.externalCloneTool` to fold an existing
clone tool's output in as one more candidate source.

## When the user runs `/dry-eyes init`

Read `references/init-flow.md` and follow it end to end. Detects the
repo's package/workspace layout and any existing clone-detection tooling,
interviews briefly about exclude patterns / output location / scan depth /
language / whether to gitignore reports / model / cross-package scope, then
**profiles the repo and designs its duplication-prone categories**,
persisting both to `.dry-eyes/config.json` and `.dry-eyes/probes.json`. If
skipped, `/dry-eyes scan` auto-bootstraps this non-interactively (sane
defaults, no questions asked) the first time it needs probes that don't
exist yet. Running it explicitly first just lets you customize things
before that happens — both files are also plain, editable JSON afterward,
the cheapest lever on recall if a category turns out to be missing.

## When the user runs `/dry-eyes scan`

Read-only — never edits code, full-repo only. Read `references/scan-flow.md`
and follow it end to end: gather this repo's deterministic duplication
signals (bootstrapping probes via `init` first if none exist), turn them
into candidate clusters, verify each one skeptically, then run an
independent multi-vote comparison on every cluster whose variants actually
diverge in behavior — each vote derives what correct behavior requires
*before* looking at any variant, and disagreement between votes is
adjudicated, never simply outvoted, since the conclusion a converged
majority is most likely to miss is exactly "none of these is right." Writes
a classified markdown + JSON report, leading with the clusters that need a
human decision.

## What this does not do (v1)

- **No `fix` command.** The JSON report has a stable id and a
  safe/risky-style classification per cluster specifically so a future
  `dry-eyes fix` can consume it later — applying a consolidation is a
  different, higher-stakes action than reporting one, and isn't built yet.
- **No diff/PR-scoped mode.** Not just deferred: duplicate detection is
  inherently a whole-repo comparison (to know if new code duplicates
  something, the "something" is almost always outside the diff), unlike a
  security lens that can reason about one changed hunk alone — a faithful
  diff-scoped version would have to sweep the whole repo anyway, losing the
  cost saving that justifies a diff mode in the first place.
- **No cross-language comparison.** Every scope is exactly one language;
  the same rule reimplemented in, say, a Go backend and a TypeScript
  frontend is out of scope for this version.
- **High-precision, medium-recall, and the report says so every time.**
  Duplication sharing no repeated literal, no shared name, no similar line
  shape, and no mirrored path is invisible to the deterministic signals,
  and the supplementary LLM sweep only catches it if a category happened to
  be designed for that area. This is stated in every report's coverage
  section, not just here.

Files in this skill

  • SKILL.md6.9 KB
  • assets/collect-signals.awk.d/agg-literals.awk1.5 KB
  • assets/collect-signals.awk.d/group-by-fileset.awk820 B
  • assets/collect-signals.awk.d/line-overlap.awk2 KB
  • assets/collect-signals.sh18.6 KB
  • assets/config.schema.json13.1 KB
  • assets/probes.schema.json6.3 KB
  • references/init-flow.md23.8 KB
  • references/scan-flow.md55.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.