# Semgrep Rule Variant Creator

Creates language variants of existing Semgrep rules.

- Repository: https://github.com/trailofbits/skills (7935 stars)
- Category: Testing
- License: CC-BY-SA-4.0
- Last updated: 2026-10-28
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add trailofbits/skills --skill semgrep-rule-variant-creator -g -a claude-code -y`
Codex: `npx skills add trailofbits/skills --skill semgrep-rule-variant-creator -g -a codex -y`
Cursor: `npx skills add trailofbits/skills --skill semgrep-rule-variant-creator -g -a cursor -y`
Gemini CLI: `npx skills add trailofbits/skills --skill semgrep-rule-variant-creator -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add trailofbits/skills`

## Description

Creates language variants of existing Semgrep rules. Use when porting a Semgrep rule to specified target languages. Takes an existing rule and target languages as input, produces independent rule+test directories for each language.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Semgrep Rule Variant Creator

Port an existing Semgrep rule to other languages, one independent test-driven cycle per
language.

For a new rule rather than a port, use `semgrep-rule-creator`, it takes a bug pattern
description where this skill takes a finished rule. That skill is also the reference for
rule-writing fundamentals: taint mode versus pattern matching, why tests come first, and
how to narrow a rule once it passes. Porting applies those same judgments in a new
language, so start there when the rule structure itself is the open question.

## Run it as a workflow

Porting is the same four phases repeated per language, so the orchestration ships as a
dynamic workflow rather than as instructions to re-follow each run:

```
/semgrep-rule-variant-creator:port-rule-to-languages
```

Pass the three required arguments, and `outputDir` unless the working directory is where you
want the variants. One language per entry: `"Go and Java"` ports a single language named after
the phrase, and the script rejects it.

`referencesDir` has to be a resolved absolute path. Resolve it here, because no workflow script
can expand a variable. Try in order, first hit wins, the `-d` is the point, since a bare `ls`
prints the names of the files inside the directory rather than the directory itself and leaves
nothing to copy:

1. **Claude Code**, `ls -d -- "${CLAUDE_PLUGIN_ROOT}/skills/semgrep-rule-variant-creator/references"`
2. **Codex**, the same command with `${CODEX_PLUGIN_ROOT}`, if that variable is set instead
3. **Neither set**, resolve `{baseDir}/references` from the directory containing this loaded
   SKILL.md and print its absolute path with `ls -d -- "<resolved path>"`. Do not search caches
   or the target project for another copy.

Then confirm the directory that printed holds both reference files, with `ls -1 -- "<that path>"`.

The rest: https://github.com/trailofbits/skills/blob/HEAD/plugins/semgrep-rule-variant-creator/skills/semgrep-rule-variant-creator/SKILL.md
