How Impeccable's Skill Prefixing Uses Regex Pattern Matching to Rename Commands
Impeccable prefixes skill references by applying two targeted regular expressions—one with a lookahead assertion for command slashes and another case-insensitive pattern for prose references—to safely rename invocations like /audit to /i-audit without breaking partial matches.
Impeccable's build system optionally adds prefixes (such as i-) to every user-invokable skill name, enabling prefixed and un-prefixed bundles to coexist without collision. This Impeccable skill prefixing regex pattern matching logic resides primarily in scripts/lib/utils.js and is executed by each provider-specific transformer. The implementation relies on precise regular expressions to distinguish between command-style invocations and natural-language references while avoiding accidental partial replacements.
The Core Algorithm in scripts/lib/utils.js
The prefixSkillReferences function exported from scripts/lib/utils.js implements the regex-based replacement strategy. It accepts the skill content, a prefix string, and an array of skill names, then returns the transformed content with all references updated.
export function prefixSkillReferences(content, prefix, skillNames) {
if (!prefix || !skillNames || skillNames.length === 0) return content;
let result = content;
// Sort longest names first → prevents "teach-impeccable" being split inside "teach"
const sorted = [...skillNames].sort((a, b) => b.length - a.length);
for (const name of sorted) {
const prefixed = `${prefix}${name}`;
// ① Replace "/skillname" command invocations
result = result.replace(
new RegExp(`\\/(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$))`, 'g'),
`/${prefix}`
);
// ② Replace natural-language references "the skillname skill"
result = result.replace(
new RegExp(`the ${escapeRegex(name)} skill`, 'gi'),
`the ${prefixed} skill`
);
}
return result;
}
Sorting Skills by Length to Prevent Partial Matches
Before applying any regex, the function sorts the skill names array in descending order by length using [...skillNames].sort((a, b) => b.length - a.length). This ensures that longer skill names containing shorter substrings are processed first. For example, teach-impeccable is handled before teach, preventing the shorter pattern from incorrectly matching inside the longer name.
Regex Pattern 1: Command-Style References with Lookahead
The first regex targets command invocations using a pattern with a positive lookahead: \\/(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$)).
\\/matches the literal forward slash starting a command.(?=...)is a positive lookahead that checks the slash is followed by the exact skill name (escapeRegex(name)) and then either a non-identifier character or the end of the string ((?:[^a-zA-Z0-9_-]|$)).- Only the slash itself is replaced with
/${prefix}, transforming/auditinto/i-auditwhile leaving/audit-extrauntouched because the lookahead fails on the hyphen.
Regex Pattern 2: Natural-Language References
The second pattern handles prose references: the ${escapeRegex(name)} skill with the gi flags for global, case-insensitive matching. This transforms phrases like "the audit skill" into "the i-audit skill" throughout documentation and instruction blocks, ensuring consistent naming in natural language contexts.
Integration Across Provider Transformers
Every provider-specific transformer—including Cursor, Claude Code, Gemini, Codex, Agents, and Kiro—invokes prefixSkillReferences after expanding placeholders. In scripts/lib/transformers/cursor.js (lines 38-41), the implementation follows this pattern:
let skillBody = replacePlaceholders(skill.body, 'cursor', commandNames);
if (prefix) skillBody = prefixSkillReferences(skillBody, prefix, allSkillNames);
The same invocation appears in transformers/gemini.js, transformers/claude-code.js, transformers/codex.js, transformers/agents.js, and transformers/kiro.js, ensuring consistent prefixing across all output formats.
Build-Time Orchestration and Output
The scripts/build.js file orchestrates the prefixed bundle generation by passing prefixOptions to each transformer:
const prefixOptions = { prefix: 'i-', outputSuffix: '-prefixed' };
transformCursor(skills, DIST_DIR, patterns, prefixOptions);
// ... other transformers
assembleUniversal(DIST_DIR, '-prefixed');
When prefixOptions.prefix is non-empty, the regex transformations generate files like dist/cursor-prefixed/.cursor/skills/i-audit/SKILL.md, containing both prefixed command names (/i-audit) and natural-language mentions ("the i-audit skill").
Summary
- Impeccable's skill prefixing relies on
prefixSkillReferencesinscripts/lib/utils.jsto inject prefixes likei-into skill references. - Two regex patterns handle distinct contexts: a lookahead-based pattern for command slashes and a case-insensitive pattern for prose references.
- Skill names are sorted by length descending to prevent shorter names from matching inside longer ones.
- Provider transformers in
scripts/lib/transformers/apply this logic uniformly across Cursor, Claude Code, Gemini, Codex, Agents, and Kiro outputs. - The
escapeRegexutility sanitizes skill names to prevent regex meta-character injection.
Frequently Asked Questions
What regex pattern does Impeccable use to detect command invocations?
Impeccable uses the pattern \\/(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$)) to detect command invocations. This regex matches a literal forward slash only when followed by the exact skill name and a non-identifier character or end of string, ensuring precise boundary detection without consuming the skill name itself.
Why does Impeccable sort skill names by length before applying regex replacements?
Impeccable sorts skill names by length in descending order (b.length - a.length) to prevent partial matches. This guarantees that longer skill names containing shorter substrings—such as teach-impeccable containing teach—are processed first, avoiding incorrect replacements inside compound names.
How does the escapeRegex function prevent injection attacks in skill names?
The escapeRegex function escapes regex meta-characters that could appear in skill names, such as dots, brackets, or quantifiers. This sanitization ensures that user-defined skill names are treated as literal strings within the regex patterns, preventing unintended pattern matching behavior or ReDoS vulnerabilities.
Which files in the Impeccable repository handle the prefixing logic?
The core logic resides in scripts/lib/utils.js within the prefixSkillReferences function. This utility is called by each provider transformer located in scripts/lib/transformers/ (including cursor.js, claude-code.js, gemini.js, codex.js, agents.js, and kiro.js). The build orchestration in scripts/build.js initiates the prefixed build process, while public/app.js provides the UI toggle for downloading prefixed bundles.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →