diff --git a/.codex/skills/audit/SKILL.md b/.codex/skills/audit/SKILL.md index 48ab66d54..1fdb07106 100644 --- a/.codex/skills/audit/SKILL.md +++ b/.codex/skills/audit/SKILL.md @@ -67,7 +67,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /animate, /quieter, /optimize, /adapt, /clarify, /distill, /delight, /onboard, /normalize, /audit, /harden, /polish, /extract, /bolder, /arrange, /typeset, /critique, /colorize, /overdrive — or other installed skills you're sure exist) +- **Suggested command**: Which command to use (prefer: $animate, $quieter, $optimize, $adapt, $clarify, $distill, $delight, $onboard, $normalize, $audit, $harden, $polish, $extract, $bolder, $arrange, $typeset, $critique, $colorize, $overdrive — or other installed skills you're sure exist) #### Critical Issues [Issues that block core functionality or violate WCAG A] @@ -104,12 +104,12 @@ Create actionable plan: ### Suggested Commands for Fixes -Map issues to available commands. Prefer these: /animate, /quieter, /optimize, /adapt, /clarify, /distill, /delight, /onboard, /normalize, /audit, /harden, /polish, /extract, /bolder, /arrange, /typeset, /critique, /colorize, /overdrive. You may also suggest other installed skills you're sure exist, but never invent commands. +Map issues to available commands. Prefer these: $animate, $quieter, $optimize, $adapt, $clarify, $distill, $delight, $onboard, $normalize, $audit, $harden, $polish, $extract, $bolder, $arrange, $typeset, $critique, $colorize, $overdrive. You may also suggest other installed skills you're sure exist, but never invent commands. Examples: -- "Use `/normalize` to align with design system (addresses N theming issues)" -- "Use `/optimize` to improve performance (addresses N performance issues)" -- "Use `/harden` to improve resilience (addresses N edge cases)" +- "Use `$normalize` to align with design system (addresses N theming issues)" +- "Use `$optimize` to improve performance (addresses N performance issues)" +- "Use `$harden` to improve resilience (addresses N edge cases)" **IMPORTANT**: Be thorough but actionable. Too many low-priority issues creates noise. Focus on what actually matters. diff --git a/.codex/skills/critique/SKILL.md b/.codex/skills/critique/SKILL.md index 6077c439a..1cf158408 100644 --- a/.codex/skills/critique/SKILL.md +++ b/.codex/skills/critique/SKILL.md @@ -98,7 +98,7 @@ For each issue: - **What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Command**: Which command to use (prefer: /animate, /quieter, /optimize, /adapt, /clarify, /distill, /delight, /onboard, /normalize, /audit, /harden, /polish, /extract, /bolder, /arrange, /typeset, /critique, /colorize, /overdrive — or other installed skills you're sure exist) +- **Command**: Which command to use (prefer: $animate, $quieter, $optimize, $adapt, $clarify, $distill, $delight, $onboard, $normalize, $audit, $harden, $polish, $extract, $bolder, $arrange, $typeset, $critique, $colorize, $overdrive — or other installed skills you're sure exist) ### Minor Observations Quick notes on smaller issues worth addressing. diff --git a/scripts/lib/transformers/factory.js b/scripts/lib/transformers/factory.js index df7e535f7..145bdd3dc 100644 --- a/scripts/lib/transformers/factory.js +++ b/scripts/lib/transformers/factory.js @@ -1,5 +1,5 @@ import path from 'path'; -import { cleanDir, ensureDir, writeFile, generateYamlFrontmatter, replacePlaceholders, prefixSkillReferences } from '../utils.js'; +import { cleanDir, ensureDir, writeFile, generateYamlFrontmatter, replacePlaceholders, prefixSkillReferences, PROVIDER_PLACEHOLDERS } from '../utils.js'; /** * Map from frontmatter field name to extraction spec. @@ -86,8 +86,9 @@ export function createTransformer(config) { const frontmatter = generateYamlFrontmatter(frontmatterObj); // Build body - let skillBody = replacePlaceholders(skill.body, provider, commandNames); - if (prefix) skillBody = prefixSkillReferences(skillBody, prefix, allSkillNames); + const cmdPrefix = (PROVIDER_PLACEHOLDERS[provider] || {}).command_prefix || '/'; + let skillBody = replacePlaceholders(skill.body, provider, commandNames, allSkillNames); + if (prefix) skillBody = prefixSkillReferences(skillBody, prefix, allSkillNames, cmdPrefix); if (bodyTransform) skillBody = bodyTransform(skillBody, skill); const content = `${frontmatter}\n\n${skillBody}`; @@ -98,7 +99,7 @@ export function createTransformer(config) { const refDir = path.join(skillDir, 'reference'); ensureDir(refDir); for (const ref of skill.references) { - const refContent = replacePlaceholders(ref.content, provider); + const refContent = replacePlaceholders(ref.content, provider, [], allSkillNames); writeFile(path.join(refDir, `${ref.name}.md`), refContent); refCount++; } diff --git a/scripts/lib/utils.js b/scripts/lib/utils.js index 86063fd89..b2f89f80b 100644 --- a/scripts/lib/utils.js +++ b/scripts/lib/utils.js @@ -271,42 +271,50 @@ export const PROVIDER_PLACEHOLDERS = { 'claude-code': { model: 'Claude', config_file: 'CLAUDE.md', - ask_instruction: 'STOP and call the AskUserQuestion tool to clarify.' + ask_instruction: 'STOP and call the AskUserQuestion tool to clarify.', + command_prefix: '/' }, 'cursor': { model: 'the model', config_file: '.cursorrules', - ask_instruction: 'ask the user directly to clarify what you cannot infer.' + ask_instruction: 'ask the user directly to clarify what you cannot infer.', + command_prefix: '/' }, 'gemini': { model: 'Gemini', config_file: 'GEMINI.md', - ask_instruction: 'ask the user directly to clarify what you cannot infer.' + ask_instruction: 'ask the user directly to clarify what you cannot infer.', + command_prefix: '/' }, 'codex': { model: 'GPT', config_file: 'AGENTS.md', - ask_instruction: 'ask the user directly to clarify what you cannot infer.' + ask_instruction: 'ask the user directly to clarify what you cannot infer.', + command_prefix: '$' }, 'agents': { model: 'the model', config_file: '.github/copilot-instructions.md', - ask_instruction: 'ask the user directly to clarify what you cannot infer.' + ask_instruction: 'ask the user directly to clarify what you cannot infer.', + command_prefix: '/' }, 'kiro': { model: 'Claude', config_file: '.kiro/settings.json', - ask_instruction: 'ask the user directly to clarify what you cannot infer.' + ask_instruction: 'ask the user directly to clarify what you cannot infer.', + command_prefix: '/' }, opencode: { model: 'Claude', config_file: 'AGENTS.md', ask_instruction: 'STOP and call the `question` tool to clarify.', + command_prefix: '/' }, 'pi': { model: 'the model', config_file: 'AGENTS.md', - ask_instruction: 'ask the user directly to clarify what you cannot infer.' + ask_instruction: 'ask the user directly to clarify what you cannot infer.', + command_prefix: '/' } }; @@ -320,8 +328,9 @@ export const PROVIDER_PLACEHOLDERS = { * @param {string} content - The skill body text * @param {string} prefix - The prefix to add (e.g., 'i-') * @param {string[]} skillNames - Array of all skill names + * @param {string} commandPrefix - The command invocation prefix (e.g., '/' or '$') */ -export function prefixSkillReferences(content, prefix, skillNames) { +export function prefixSkillReferences(content, prefix, skillNames, commandPrefix = '/') { if (!prefix || !skillNames || skillNames.length === 0) return content; let result = content; @@ -331,8 +340,12 @@ export function prefixSkillReferences(content, prefix, skillNames) { for (const name of sorted) { const prefixed = `${prefix}${name}`; - // Replace `/skillname` references (command invocations) - result = result.replace(new RegExp(`\\/(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$))`, 'g'), `/${prefix}`); + // Replace command invocations (e.g., `/skillname` or `$skillname`) with prefixed versions + const escapedPrefix = escapeRegex(commandPrefix); + result = result.replace( + new RegExp(`${escapedPrefix}(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$))`, 'g'), + `${commandPrefix}${prefix}` + ); // Replace `the skillname skill` references result = result.replace( @@ -350,18 +363,34 @@ function escapeRegex(str) { const EXCLUDED_FROM_SUGGESTIONS = new Set(['teach-impeccable', 'i-teach-impeccable']); -export function replacePlaceholders(content, provider, commandNames = []) { +export function replacePlaceholders(content, provider, commandNames = [], allSkillNames = []) { const placeholders = PROVIDER_PLACEHOLDERS[provider] || PROVIDER_PLACEHOLDERS['cursor']; + const cmdPrefix = placeholders.command_prefix || '/'; const commandList = commandNames .filter(n => !EXCLUDED_FROM_SUGGESTIONS.has(n)) - .map(n => `/${n}`) + .map(n => `${cmdPrefix}${n}`) .join(', '); - return content + let result = content .replace(/\{\{model\}\}/g, placeholders.model) .replace(/\{\{config_file\}\}/g, placeholders.config_file) .replace(/\{\{ask_instruction\}\}/g, placeholders.ask_instruction) + .replace(/\{\{command_prefix\}\}/g, cmdPrefix) .replace(/\{\{available_commands\}\}/g, commandList); + + // Replace `/skillname` invocations with the correct command prefix for this provider + // (e.g., `/normalize` → `$normalize` for Codex) + if (cmdPrefix !== '/' && allSkillNames.length > 0) { + const sorted = [...allSkillNames].sort((a, b) => b.length - a.length); + for (const name of sorted) { + result = result.replace( + new RegExp(`\\/(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$))`, 'g'), + cmdPrefix + ); + } + } + + return result; } /**