Understanding the replacePlaceholders Function for Provider-Specific Tokens in Impeccable
The replacePlaceholders function serves as the central content adapter that injects provider-specific values into mustache-style tokens during Impeccable's build process, transforming generic source files into tailored outputs for Cursor, Claude-Code, Gemini, Codex, Kiro, and Agents.
When building distribution packages for multiple AI coding assistants, the pbakaus/impeccable repository relies on generic markdown templates stored in source/skills/ and source/commands/. The replacePlaceholders utility in scripts/lib/utils.js bridges these generic sources with provider-specific requirements, ensuring each LLM receives correctly branded configuration files and command instructions.
How replacePlaceholders Transforms Generic Content
The Token Replacement Mechanism
Located at lines 336-348 of scripts/lib/utils.js, the replacePlaceholders function accepts three parameters: the template string (skillBody), the provider identifier, and an array of command names. It scans the input text for mustache-style tokens and substitutes them with values drawn from the PROVIDER_PLACEHOLDERS configuration map defined at lines 266-297.
Supported Tokens and Data Sources
The function recognizes four primary tokens, each mapping to provider-specific values:
- {{model}}: Replaced with the human-readable model name (e.g., "Claude", "Gemini", "GPT") sourced from
PROVIDER_PLACEHOLDERS[provider].model - {{config_file}}: Substituted with the provider's configuration filename (e.g.,
CLAUDE.md,GEMINI.md) fromPROVIDER_PLACEHOLDERS[provider].config_file - {{ask_instruction}}: Inserted with provider-specific guidance on user clarification methods from
PROVIDER_PLACEHOLDERS[provider].ask_instruction - {{available_commands}}: Populated with a comma-separated list filtered by
EXCLUDED_FROM_SUGGESTIONSand prefixed according to provider configuration
Implementation Across Provider Transformers
During the build process, each provider's transformer invokes the function to adapt generic source files into distribution-ready content. For example, the Gemini transformer at scripts/lib/transformers/gemini.js (lines 36-41) prepares command names and executes the replacement:
const commandNames = skills.filter(s => s.userInvokable).map(s => `${prefix}${s.name}`);
let skillBody = replacePlaceholders(skill.body, 'gemini', commandNames);
// Additional Gemini‑specific handling follows...
This pattern repeats across scripts/lib/transformers/cursor.js, claude-code.js, codex.js, kiro.js, and agents.js, ensuring consistent token handling while allowing each transformer to focus on file layout specifics.
Practical Usage Examples
Direct Function Call
You can import and use replacePlaceholders directly to preview how content transforms for specific providers:
import { replacePlaceholders } from './scripts/lib/utils.js';
const genericBody = `
Use the {{model}} model to generate a design.
Configuration lives in {{config_file}}.
If you get stuck, {{ask_instruction}}
Available commands: {{available_commands}}
`;
const commandNames = ['/design', '/preview']; // user‑invokable commands
const result = replacePlaceholders(genericBody, 'gemini', commandNames);
console.log(result);
Output for Gemini:
Use the Gemini model to generate a design.
Configuration lives in GEMINI.md.
If you get stuck, ask the user directly to clarify what you cannot infer.
Available commands: /design, /preview
Provider Placeholder Configuration
The mapping of tokens to values resides in the PROVIDER_PLACEHOLDERS export:
export const PROVIDER_PLACEHOLDERS = {
'claude-code': {
model: 'Claude',
config_file: 'CLAUDE.md',
ask_instruction: 'STOP and call the AskUserQuestionTool to clarify.'
},
'gemini': {
model: 'Gemini',
config_file: 'GEMINI.md',
ask_instruction: 'ask the user directly to clarify what you cannot infer.'
},
// …cursor, codex, kiro, agents
};
Architectural Benefits of Centralized Replacement
Centralizing token substitution through replacePlaceholders delivers three key advantages:
- Consistency: Every provider receives identically structured content with correctly localized values, eliminating manual copy-paste errors across six different target platforms
- Extensibility: Adding support for new LLM providers requires only extending the
PROVIDER_PLACEHOLDERSmap; the build pipeline and transformer logic remain untouched - Separation of Concerns: Transformer files handle directory structures and file naming conventions while the utility manages content adaptation, adhering to single-responsibility principles
Summary
- The
replacePlaceholdersfunction inscripts/lib/utils.js(lines 336-348) is the core utility for provider-specific content adaptation in pbakaus/impeccable - It substitutes four mustache-style tokens—
{{model}},{{config_file}},{{ask_instruction}}, and{{available_commands}}—with values from thePROVIDER_PLACEHOLDERSmap (lines 266-297) - Provider transformers in
scripts/lib/transformers/call this function during the build process to convert generic source files into tailored distribution outputs - The function filters command names through
EXCLUDED_FROM_SUGGESTIONSand applies prefixes when generating the available commands list - This centralized approach ensures consistent output across Cursor, Claude-Code, Gemini, Codex, Kiro, and Agents while simplifying maintenance and provider onboarding
Frequently Asked Questions
What specific tokens does replacePlaceholders support?
The function supports four mustache-style tokens: {{model}} for the human-readable model name, {{config_file}} for the provider's documentation filename, {{ask_instruction}} for clarification guidance, and {{available_commands}} for the filtered list of user-invokable commands. Each token maps to provider-specific values defined in the PROVIDER_PLACEHOLDERS constant at lines 266-297 of scripts/lib/utils.js.
How does replacePlaceholders generate the available_commands list?
The function receives the commandNames array from the calling transformer, which contains only user-invokable commands filtered by the EXCLUDED_FROM_SUGGESTIONS set. It then joins these commands with commas, applying any configured prefix (such as /) before insertion into the template. This ensures generated help text accurately reflects only the commands relevant to end users.
Where is the PROVIDER_PLACEHOLDERS configuration defined?
The placeholder mapping is defined as a constant export in scripts/lib/utils.js at lines 266-297. This configuration object contains nested objects for each supported provider—including 'claude-code', 'cursor', 'gemini', 'codex', 'kiro', and 'agents'—each specifying the model name, config file, and ask instruction strings.
Can replacePlaceholders be used for custom provider integrations?
Yes, the function is designed for extensibility. To support a new LLM provider, you only need to add a new entry to the PROVIDER_PLACEHOLDERS map with the appropriate model name, configuration filename, and instruction text. The existing build pipeline and transformer files will automatically utilize these values without requiring changes to the core replacement logic in scripts/lib/utils.js.
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 →